encodeLeaf encodes a leaf error. This function accepts a `causes` argument because we encode multi-cause errors using the Leaf protobuf. This was done to enable backwards compatibility when introducing this functionality since the Wrapper type already has a required single `cause` field.
(ctx context.Context, err error, causes []error)
| 42 | // introducing this functionality since the Wrapper type already has a |
| 43 | // required single `cause` field. |
| 44 | func encodeLeaf(ctx context.Context, err error, causes []error) EncodedError { |
| 45 | var msg string |
| 46 | var details errorspb.EncodedErrorDetails |
| 47 | |
| 48 | if e, ok := err.(*opaqueLeaf); ok { |
| 49 | msg = e.msg |
| 50 | details = e.details |
| 51 | } else if e, ok := err.(*opaqueLeafCauses); ok { |
| 52 | msg = e.msg |
| 53 | details = e.details |
| 54 | } else { |
| 55 | details.OriginalTypeName, details.ErrorTypeMark.FamilyName, details.ErrorTypeMark.Extension = getTypeDetails(err, false /*onlyFamily*/) |
| 56 | |
| 57 | var payload proto.Message |
| 58 | |
| 59 | // If we have a manually registered encoder, use that. |
| 60 | typeKey := TypeKey(details.ErrorTypeMark.FamilyName) |
| 61 | if enc, ok := leafEncoders[typeKey]; ok { |
| 62 | msg, details.ReportablePayload, payload = enc(ctx, err) |
| 63 | } else { |
| 64 | // No encoder. Let's try to manually extract fields. |
| 65 | |
| 66 | // The message comes from Error(). Simple. |
| 67 | msg = err.Error() |
| 68 | |
| 69 | // If there are known safe details, use them. |
| 70 | if s, ok := err.(SafeDetailer); ok { |
| 71 | details.ReportablePayload = s.SafeDetails() |
| 72 | } |
| 73 | |
| 74 | // If it's also a protobuf message, we'll use that as |
| 75 | // payload. DecodeLeaf() will know how to turn that back into a |
| 76 | // full error if there is no decoder. |
| 77 | payload, _ = err.(proto.Message) |
| 78 | } |
| 79 | // If there is a detail payload, encode it. |
| 80 | details.FullDetails = encodeAsAny(ctx, err, payload) |
| 81 | } |
| 82 | |
| 83 | var cs []*EncodedError |
| 84 | if len(causes) > 0 { |
| 85 | cs = make([]*EncodedError, len(causes)) |
| 86 | for i, ee := range causes { |
| 87 | ee := EncodeError(ctx, ee) |
| 88 | cs[i] = &ee |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | return EncodedError{ |
| 93 | Error: &errorspb.EncodedError_Leaf{ |
| 94 | Leaf: &errorspb.EncodedErrorLeaf{ |
| 95 | Message: msg, |
| 96 | Details: details, |
| 97 | MultierrorCauses: cs, |
| 98 | }, |
| 99 | }, |
| 100 | } |
| 101 | } |
no test coverage detected
searching dependent graphs…