Comments (16)
from errors.
Most important point: This is about errors.Cause working without any surprises. errors.Cause() returning nil when the input is non-nil is a surprise. Neither the code nor the documentation cover this.
Is the bug that the Cause implmentation on myCodedError returns whatever is in its err field without checking it is nil?
Yes.
Could this be solved by changing the contract on the causer interface to specific that Cause should not return nil? I can see the argument for allow Cause to return nil, but i'd like to understand what the use case for this is.
Yes it could be solved by changing the contract of causer. It would be a documentation issue then, correct?
The use case for this is interoping with custom error types which implement causer and whether they'll always return non-nil errors. In some cases this could be a programming mistake and other cases it could be purposeful.
Do we mandate non-nil errors via documentation or a panic? Or treat nil errors from causer as 'this causer has no underlying error, so return it EDIT: it being the causer, not the nil underlying error'.
from errors.
Ok, I just ran into this, but what I expected was to be able to do this:
func (err *sdkError) Cause() error {
if err.cause != nil {
return err.cause
}
return err
}
Sometimes *sdkError has a .cause
, sometimes it doesn't -- it's up to the user. And when an error doesn't have another cause to blame, it is the underlying cause. Right? :)
- If you think
Cause
meansImmediateCause
, then you'd expect the underlying error to return nil onCause
. - If you think
Cause
meansUnderlyingCause
, then you'd expect to always return the root/underlying error and never nil or any intermediary errors. - If you think
Cause
meansBlameCause
, then you'd return the immediate cause, or the current error if you couldn't blame another error.
Made a PR (see link) to handle all use-cases (return nil or self as cause).
from errors.
Is the bug that the Cause implmentation on myCodedError returns whatever is in its err field without checking it is nil?
Could this be solved by changing the contract on the causer interface to specific that Cause should not return nil? I can see the argument for allow Cause to return nil, but i'd like to understand what the use case for this is.
from errors.
I just ran into this, and it was a surprise to me. Here is the code I used: https://play.golang.org/p/RYXqML2VAw
Basically, gorilla's securecookie happens to have the same interface, but with different semantics. I did not realize this, and was very confused why it was returning nil.
I love this errors package, and it's never failed me. I guess my two cents would be that if an error is not nil, but it's Cause()
returns nil, then errors.Cause
should return the original error, if that makes sense. I understand if this goes against your original intention though.
from errors.
I agree. That second change is almost exactly what I used in my code right now as a work around. I also think the second way matches semantically with what the docs say (with some liberal interpretation):
Cause returns the underlying cause of the error, if possible.
I guess I'm assuming a non-nil error always has a non-nil cause. But I guess in programming, it often seems like things break for no reason :)
Would you like me to submit a PR with this? I think it might also be good to add a quick sentence in the docs right after the other sentences about the causer interface. Something like: "If Cause() returns nil, the original error is returned". Or maybe a warning about how other packages may have the same cause interface with different semantics?
from errors.
is this ok?
https://github.com/chanxuehong/errors/blob/master/func.go#L90
from errors.
That looks good to me. If I'm reading it right, a non-nil error always has a non-nil cause, which was my original issue. The only thing I might suggest is adding a sentence to the doc saying this.
from errors.
from errors.
I don’t think a Cause() should ever be expected to return nil, however, I do suppose it is a possible return value from an implementation, and as such, it should be handled gracefully.
from errors.
I would appreciate it if you can help me understand, on #89, not this
PR, your use case, and why this change is necessary, and could your
requirement be handled without changing the operation of Cause?
I wrote a bit up there (see sdkError
example).
We need sdkError
because in the SDK, every such error should also have a numeric code for the type of error. When you create an sdkError
, you specify a numeric code and any log information for debugging purposes. Sometimes you'll want to attach an immediate cause for creating the sdkError
, but other times there will be no immediate cause. So sdkError.Cause()
sometimes needs to return nil/itself, and sometimes another error.
Of course it would be sufficient to allow errors.Cause()
to handle nil
return values from causer.Cause()
, but it would also be nice to allow the implementor of causer
to return itself as the cause, signifying that it is the underlying cause. It would have been the least surprising behavior for me.
from errors.
from errors.
I can't use With* to wrap the cause because it needs to be wrapped by sdkError, but I can do the former of having two errors, one that embeds the other and also has a cause field.
Thank you, and looking forward to the results of the survey. LMK if I can help.
from errors.
Can we create a new RootCause
function and deprecate the existing Cause
function? That will satisfy backwards compatibility. Cause
would only be dropped in a breaking release.
from errors.
Hi Greg,
What would this new RootCause
function do?
from errors.
It would just fix this bug.
from errors.
Related Issues (20)
- Proposal: add errors.Is and errors.As
- RFC: Allow custom StackTraces
- func Is() does not works with errors.Wrap or errors.Wrapf HOT 3
- Cause() behavior has changed HOT 11
- respect -trimpath build flag HOT 3
- Unwrap doesn't return the base error HOT 7
- Questions about extending annotations HOT 5
- undefined errors.Wrap HOT 2
- How to change format return wrapped error message HOT 2
- Stacktrace don't print all stack HOT 6
- errors.Wrap() created bugs in our codebase. HOT 3
- StackTrace.Format with "%+v" includes a leading newline HOT 1
- A new error caused by another error HOT 7
- Demo
- Change Wrap() to return an error even if we provide nil HOT 3
- return *stack instead of stack HOT 2
- Wrap() duplicates call stack HOT 6
- Elegant way to check error is wrapped HOT 4
- `Errorf` should be able to wrap errors HOT 4
- Package errors looking for new maintainers HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from errors.