Skip to content
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: explain handling of nil err in documentation of FromError #4161

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ func FromProto(s *spb.Status) *Status {
return status.FromProto(s)
}

// FromError returns a Status representing err if it was produced from this
// package or has a method `GRPCStatus() *Status`. Otherwise, ok is false and a
// Status is returned with codes.Unknown and the original error message.
// FromError returns a Status representing err.
// If err is nil, ok is true and a Status with codes.OK is returned.
// If it has a method `GRPCStatus() *Status`, ok is true and this value is returned.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errorf()'s return values have the method GRPCStatus() *Status; however, this is not documented anywhere. It should be explicit that this function turns errors produced by Errorf or (*Status).Err() into *Statuses, as that is its primary function.

Why not something more like the original text?

// FromError returns a Status representing err if it was produced by this
// package or has a method `GRPCStatus() *Status`.
// If err is nil, a Status is returned with codes.OK and no message.
// Otherwise, ok is false and a Status is returned with codes.Unknown and
// the original error message.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the end it's up to you. My goal by changing that was to make it very explicit that we return ok=true for err==nil because that can be against intuition if you are under the impression this works like a type assertion.

Take the following code fragment as example:

func doSomething() error {
  return nil
}
// ...
err := doSomething()
if err, ok := err.(*SpecificType); ok {
   // common style to check for error, see https://blog.golang.org/go1.13-errors#TOC_2.1.
}

if status, ok := status.FromError(err); ok {
   // oh status is actually OK so no error happened. So this code is wrong.
   // The writer was under the wrong impression that this works like the case above
}

Feel free to change this PR if you have an idea about how to improve it better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal by changing that was to make it very explicit that we return ok=true for err==nil

The text I proposed above seems pretty explicit that ok=true when err=nil, as that case is documented above the "Otherwise, ok is false" sentence.

Your example code is highly unusual. Why would you test err to see what type it is before checking to see if there even was an error by comparing with nil?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems your judgement about this issue is different from mine. I really don't mind and accept that and will close this PR. There are probably more important fixes waiting than this.
Feel free to close the linked issue and tag it with "Wontfix".

// Otherwise, ok is false and a Status is returned with
// codes.Unknown and the original error message.
func FromError(err error) (s *Status, ok bool) {
if err == nil {
return nil, true
Expand Down