-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
status: handle wrapped errors #6031
Conversation
|
Hello, @easwars. Please take a look at PR. It seems like a small one =) |
@psyhatter : Just wondering the use case behind the change? I agree that it would be nice for the status package to handle wrapped errors. @dfawley : As I understand, this would be a behavior change. I vaguely remember issues/PRs/questions about switching the status package to support wrapped errors in the past, but I don't quite remember the outcome of those discussions. I feel that this would a good change. If we go with this, we would need to update the docstrings for these functions and also make a bigger noise in the release notes. But I also wanted to check with your thoughts on this before proceeding much further with the review. |
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'm okay with this particular aspect of error wrapping. IIRC we didn't do this earlier because errors.As
was too new for us to use given our Go verison support policy.
But we should take a look over the old related issues/PRs and make sure we aren't forgetting anything that we decided previously.
Suppose we have a sentinel error: package model
import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
var ErrUserNotFound = status.Errorf(codes.NotFound, "user not found") At the repository level, we return this sentinel error so that it can be handled at the service level with sender, err := s.repo.GetUser(ctx, senderID)
if err != nil {
return fmt.Errorf("getting sender: %w", err)
}
receiver, err := s.repo.GetUser(ctx, receiverID)
if err != nil {
return fmt.Errorf("getting receiver: %w", err)
} But in this case, the grpc server will return an incorrect error code, because it uses this function, which does not know how to parse wrapped errors Probably, sentinel errors used at the service level should not implement transporter level errors, and there should be some kind of transformation. But this is a fairly convenient way when there is only one transport layer |
@easwars what this pr waiting for? |
Nothing. Why do you ask? |
Moving to @dfawley for second set of eyes. |
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.
LGTM, except for 2 small nits.
status/status.go
Outdated
// *Status`, the appropriate Status is returned. Function takes into account if | ||
// such errors have been wrapped. |
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.
Nit: this is not a complete sentence, and doesn't explain clearly (to me, anyway) what's happening. Maybe:
// - If err was produced by this package or implements the method `GRPCStatus()
// *Status`, or if err wraps a type satisfying this, the appropriate Status is returned.
status/status_test.go
Outdated
@@ -144,6 +145,37 @@ func (s) TestFromErrorOK(t *testing.T) { | |||
} | |||
} | |||
|
|||
func (s) TestFromErrorWrapped(t *testing.T) { | |||
code, message := codes.Internal, "test description" |
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.
Nit:
const code, message = codes.Internal, "test description"
(to avoid these being mutable variables when they should be invariants.)
And the other test cases, below.
RELEASE NOTES:
status.Code
andstatus.FromError
handle wrapped errors