@@ -142,10 +142,20 @@ func Code(err error) codes.Code {
142142 }
143143
144144 if wrapped , ok := err .(multiUnwrapper ); ok {
145+ var hasUnknown bool
146+
145147 for _ , err := range wrapped .Unwrap () {
146- if c := Code (err ); c != codes .OK && c != codes .Unknown {
148+ c := Code (err )
149+ if c != codes .OK && c != codes .Unknown {
147150 return c
148151 }
152+ if c == codes .Unknown {
153+ hasUnknown = true
154+ }
155+ }
156+
157+ if hasUnknown {
158+ return codes .Unknown
149159 }
150160 }
151161
@@ -159,7 +169,7 @@ func WrapCode(err error, code codes.Code) error {
159169// AsGRPCStatus tries to extract a gRPC status from the error.
160170// Supports `Unwrap() error` and `Unwrap() []error` for wrapped errors.
161171// When the `Unwrap() []error` returns multiple errors, the first one that
162- // contains a gRPC status is returned.
172+ // contains a gRPC status that is not OK is returned with the full error message .
163173func AsGRPCStatus (err error ) (* status.Status , bool ) {
164174 if err == nil {
165175 return nil , true
@@ -178,8 +188,17 @@ func AsGRPCStatus(err error) (*status.Status, bool) {
178188
179189 if wrapped , ok := err .(multiUnwrapper ); ok {
180190 for _ , err := range wrapped .Unwrap () {
181- if st , ok := AsGRPCStatus (err ); ok && st != nil {
182- return st , true
191+ st , ok := AsGRPCStatus (err )
192+ if ! ok {
193+ continue
194+ }
195+
196+ if st != nil && st .Code () != codes .OK {
197+ // Copy the full status so we can set the full error message
198+ // Does the proto conversion so can keep any extra details.
199+ proto := st .Proto ()
200+ proto .Message = err .Error ()
201+ return status .FromProto (proto ), true
183202 }
184203 }
185204 }
0 commit comments