Skip to content
This repository has been archived by the owner on Dec 1, 2021. It is now read-only.

Proposal: Wrap(nil) should not return nil #174

Closed
adamzdara opened this issue Oct 29, 2018 · 9 comments
Closed

Proposal: Wrap(nil) should not return nil #174

adamzdara opened this issue Oct 29, 2018 · 9 comments

Comments

@adamzdara
Copy link

I have recently run several times into issue when I or somebody else copied error handling code from some other case:

if err != nil {
  return errors.Wrap(err, "some message")
}

and used it for handling of some cases when err is nil and did not changed Wrap() function to New() eg:

// err was previously declared for some other error handling
if a <= 0 {
 return errors.Wrap(err, "a must be positive")
}

...and this is problem because in this case function will terminate with error but returns nil (because errors.Wrap(nil) returns nil). So my proposal here is to change this behaviour in this case to return errors.New(message) instead of nil.

@mfridman
Copy link

I think the package is functioning as intended.

In the case above you should return errors.New() because the error was already handled. I think it's beyond the scope of this package to annotate an unhandled error.

@CreatCodeBuild
Copy link

@adamzdara consider this thread #90

@puellanivis
Copy link

While pkg/errors has not hit v1.0 there are a number of people already relying upon the behavior of this library, and as such, pkg/errors is considered to be covered under the same guidelines as the Go 1.0 consistency guidelines.

As the documentation clearly states that the intended behavior is that errors.Wrap will return nil if the err == nil, we cannot just change this behavior without breaking other people’s code.

It is not and cannot be the purpose of this package to help developers ensure that they have not copy-pasted inappropriate code from one line to another.

@adamzdara
Copy link
Author

All makes sense. Just wanted to make sure that this is intentional. Will fork it for me. Thank you for info.

@CreatCodeBuild
Copy link

I also want to know why you want to return a new error when the function you are calling doesn't?

@puellanivis
Copy link

puellanivis commented Oct 30, 2018

I also want to know why you want to return a new error when the function you are calling doesn't?

This is quite common in, for example, http.Client wrappers, where a return of err == nil in http.Client.Do means only that there was no error in the HTTP protocol. However, the http.Response may have a 4xx/5xx error in the StatusCode field which is not an HTTP protocol error, but rather an API-level error. In this case one then needs to use errors.New to return the API error to the caller of the wrapper.

But since one needs the http.Response from the http.Client.Do, one must have an err defined at the same scope. So, now one has an err defined, which will ensure that errors.Wrap(err, ...) will not throw a compile-time error. And now one has mistakenly created a bug.

@cben
Copy link

cben commented Jan 9, 2020

ref: this was also discussed on #90.

@cben
Copy link

cben commented Jan 9, 2020

My personal conclusion is that while I have a case in mind where I want a nil=>nil behavior, I don't want to spell this Wrapf(err, "Problem") because that's entirely unobvious to the reader.
The opposite is not obvious either — the "wrap" is just not a verb that has obvious meaning on nothing... If it was say "annotate", it would maybe lean towards nil=>nil.
So if I rely on nil=>nil, I'd want a very explicit name to draw attention, e.g. WrapIfError or something.

I'll only use Wrapf inside if err != nil blocks where there is not ambiguity.
And in complex cases, I guess I better do if { ... Wrapf... } else { ...New... }.

P.S. compare also to fmt.Errorf("...%w...", err) which always returns an error, matching %v behavior before %w was invented, and matching what you'd expect from "formatting".

@puellanivis
Copy link

As noted in #90, it is too late to change the behavior and semantics of this package.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants