-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(grpc): preserve unknown detail types when decoding gRPC errors #5905
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
c9db49b
to
79dccda
Compare
@@ -45,7 +46,7 @@ func ToGRPC(ctx context.Context, err error) error { | |||
|
|||
// If the original error was wrapped with more context than the GRPCStatus error, | |||
// copy the original message to the GRPCStatus error | |||
if err.Error() != st.Message() { | |||
if errorHasMoreContext(err, st) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the case where we don't want the original details (or ones set in FromGRPC) to not be added into this error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AsGRPCStatus()
unwraps until it finds something implementing GRPCStatus()
. So if we had something like errors.Wrap(errors.Wrap(st.Err(), "foo") "bar")
, it would discard the foo: bar:
prefix otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for the opposite, st.Err().Error()
prepends the code to st.Message()
so naively setting the message again would duplicate the prefix that corresponds to the codes.Code
.
Check this playground https://go.dev/play/p/UKFRlAyVlYT
79dccda
to
8630be0
Compare
util/grpcerrors/grpcerrors.go
Outdated
if errMessage := err.Error(); len(errMessage) > len(st.Message()) { | ||
// check if the longer message in errMessage is only due to | ||
// prepending with the status code | ||
prefix := st.Code().String() + ": " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this trying to mimic grpcStatusError.Error()
. In that case looks like it is more complicated as some codes have special meaning. Type checking to *grpcStatusError
could be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the check to use *grpcStatusError
, let me know if that's what you had in mind. Thanks!
If decoding the status fails, retain the original proto message by registering it as a detail. This change also adds a test to verify that unknown types are preserved when: - Decoding a gRPC error with unknown detail types. - Re-encoding and decoding the error using ToGRPC / FromGRPC. Additionally, fix an issue where the codes.Code string prefix was not handled correctly, resulting in a duplicate prefix. Signed-off-by: Alberto Garcia Hierro <[email protected]>
8630be0
to
5848d95
Compare
// errorHasMoreContext checks if the original error provides more context by having | ||
// a different message or additional details than the Status. | ||
func errorHasMoreContext(err error, st *status.Status) bool { | ||
if errMessage := err.Error(); len(errMessage) > len(st.Message()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's this length check for?
If decoding the status fails, retain the original proto message by
registering it as a detail.
This change also adds a test to verify that unknown types are preserved when:
Additionally, fix an issue where the codes.Code string prefix was
not handled correctly, resulting in a duplicate prefix.