package http3 import ( "errors" "fmt" quic "github.com/refraction-networking/uquic" ) // Error is returned from the round tripper (for HTTP clients) // and inside the HTTP handler (for HTTP servers) if an HTTP/3 error occurs. // See section 8 of RFC 9114. type Error struct { Remote bool ErrorCode ErrCode ErrorMessage string } var _ error = &Error{} func (e *Error) Error() string { s := e.ErrorCode.string() if s == "" { s = fmt.Sprintf("H3 error (%#x)", uint64(e.ErrorCode)) } // Usually errors are remote. Only make it explicit for local errors. if !e.Remote { s += " (local)" } if e.ErrorMessage != "" { s += ": " + e.ErrorMessage } return s } func maybeReplaceError(err error) error { if err == nil { return nil } var ( e Error strErr *quic.StreamError appErr *quic.ApplicationError ) switch { default: return err case errors.As(err, &strErr): e.Remote = strErr.Remote e.ErrorCode = ErrCode(strErr.ErrorCode) case errors.As(err, &appErr): e.Remote = appErr.Remote e.ErrorCode = ErrCode(appErr.ErrorCode) e.ErrorMessage = appErr.ErrorMessage } return &e }