-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: errors: allow implementing err.Is(err) == false #40675
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
Comments
It was a deliberate choice to not permit I do not believe we should make any changes to support non-pure errors. |
None of this nuance has been well conveyed to users. Bare minimum we need to update the documentation, and should add the vet check too, if this is a canonical opinion. That being said, the |
Based on the conversation above, this seems like a likely decline. |
This is not a breaking change. |
Allowing errors.Is(err1, err1) == false will certainly break Go code and flies in the face of a decade of assuming that errors are equal to themselves. No. |
You seem to be arguing about the abstract idea of error I am understanding if you hold this idea as more important, but I want to be clear, I do not understand how this change is breaking. It is also definitely confusing that I can implement functionality in an |
@carnott-snap Better docs are always appreciated. Discussions about the exact nature of a breaking change take precious time and don't seem likely to lead to a productive result. As @rsc says, allowing |
No change in consensus, so declined. |
No, I see your reasons to not do this, just being pedantic about what constitutes a breaking change. |
Being pedantic when you understand what we mean is kind of a waste of everyone's time. Please don't do that. |
Precision and wording is important; I understand why you are opposed to the change, but still do not know what you define as a breaking change. |
background
Currently you can implement,
func (MyError) Is(target) bool { return true }
, butMyError.Is
will only be called iftarget != nil
, see #40673, and!reflectlite.TypeOf(target).Comparable() || err != target
. This can be confusing to implementers ofinterface{ Is(error) bool }
, because it disallows impure implementations and explicitly signalling that errors are not equal.description
I propose moving the
isComparable
check fromerrors.Is
down below the call tox.Is(target). This will hand full control of equality checking to
interface { Is(error) bool }`, and make the user experience more consistent.costs
It is my understanding that few people have implemented
interface { Is(error) bool }
, such that ``((err == target) == false) == err.Is(target)`, however if you have, you are either relying upon undefined behaviour or have a bug. That being said, this is a semantic change, so we should be careful to understand what the impact is.alternatives
If the current implementation is preferred, it should be explicitly documented.
[I]f it is equal to that target or if it implements a method Is(error) bool such that Is(target) returns true
does not describe precedence, short circuiting, or function purity. I think we should either document:interface{ Is(error) bool }
implementations should be pureerr == target
may cause((err == target) == false) == err.Is(target)
The text was updated successfully, but these errors were encountered: