Skip to content

Commit bddd2f9

Browse files
authored
Add NewWireError (connectrpc#437)
1 parent 0654729 commit bddd2f9

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

error.go

+19
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,25 @@ func NewError(c Code, underlying error) *Error {
118118
return &Error{code: c, err: underlying}
119119
}
120120

121+
// NewWireError is similar to [NewError], but the resulting *Error returns true
122+
// when tested with [IsWireError].
123+
//
124+
// This is useful for clients trying to propagate partial failures from
125+
// streaming RPCs. Often, these RPCs include error information in their
126+
// response messages (for example, [gRPC server reflection] and
127+
// OpenTelemtetry's [OTLP]). Clients propagating these errors up the stack
128+
// should use NewWireError to clarify that the error code, message, and details
129+
// (if any) were explicitly sent by the server rather than inferred from a
130+
// lower-level networking error or timeout.
131+
//
132+
// [gRPC server reflection]: https://github.com/grpc/grpc/blob/v1.49.2/src/proto/grpc/reflection/v1alpha/reflection.proto#L132-L136
133+
// [OTLP]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#partial-success
134+
func NewWireError(c Code, underlying error) *Error {
135+
err := NewError(c, underlying)
136+
err.wireErr = true
137+
return err
138+
}
139+
121140
// IsWireError checks whether the error was returned by the server, as opposed
122141
// to being synthesized by the client.
123142
//

protocol_connect.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -943,8 +943,7 @@ func (e *connectWireError) asError() *Error {
943943
if e.Code < minCode || e.Code > maxCode {
944944
e.Code = CodeUnknown
945945
}
946-
err := NewError(e.Code, errors.New(e.Message))
947-
err.wireErr = true
946+
err := NewWireError(e.Code, errors.New(e.Message))
948947
if len(e.Details) > 0 {
949948
err.details = make([]*ErrorDetail, len(e.Details))
950949
for i, detail := range e.Details {

protocol_grpc.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,7 @@ func grpcErrorFromTrailer(bufferPool *bufferPool, protobuf Codec, trailer http.H
701701
return errorf(CodeInternal, "gRPC protocol error: invalid error code %q", codeHeader)
702702
}
703703
message := grpcPercentDecode(bufferPool, trailer.Get(grpcHeaderMessage))
704-
retErr := NewError(Code(code), errors.New(message))
705-
retErr.wireErr = true
704+
retErr := NewWireError(Code(code), errors.New(message))
706705

707706
detailsBinaryEncoded := trailer.Get(grpcHeaderDetails)
708707
if len(detailsBinaryEncoded) > 0 {

0 commit comments

Comments
 (0)