-
Notifications
You must be signed in to change notification settings - Fork 209
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
Are error comparisons supported? #24
Comments
Since it may be relevant, here's something I've used when I wanted to compare error (strings): // equalError reports whether errors a and b are considered equal.
// They're equal if both are nil, or both are not nil and a.Error() == b.Error().
func equalError(a, b error) bool {
return a == nil && b == nil || a != nil && b != nil && a.Error() == b.Error()
} |
Thanks! I'm doing that currently. Just double checking to make sure I wasn't missing something. |
Hi @gnahckire, it's intentional that this package does not handle errors by default since there's no sensible policy that works for every use case, and it's the responsibility of the user to define the one that makes sense. Some simple comparers that you could use: // equateNilError reports errors to be equal only if both are nil.
equateNilError := cmp.Comparer(func(x, y error) bool {
return x == nil && y == nil
}) // equateAnyError reports errors to be equal only if both are nil or both are non-nil.
equateAnyError := cmp.Comparer(func(x, y error) bool {
return (x == nil) == (y == nil)
}) What @shurcooL suggests is a possibility, but I want to warn you that the error message provided by most packages is not stable, and something as simple as a grammar change can break your test. If you are simply checking that error messages from your own package match, then this approach is fine. // equateErrorMessage reports errors to be equal if both are nil
// or both have the same message.
equateErrorMessage := cmp.Comparer(func(x, y error) bool {
if x == nil || y == nil {
return x == nil && y == nil
}
return x.Error() == y.Error()
}) Even more advanced, if you know properties about the errors you expect, you can write better equate functions: // sentinelErrors is a set of common sentinel errors
// (i.e., those that are safe to compare directly using the == operator.
sentinelErrors := map[error]bool{io.EOF: true, io.ErrUnexpectedEOF: true, ...}
equateError := cmp.Comparer(func(x, y error) bool {
if x == nil || y == nil {
return x == nil && y == nil
}
// Check if x and y are sentinel errors.
if sentinelErrors[x] || sentinelErrors[y] {
return x == y
}
// Compare error based on their properties.
switch {
case os.IsExist(x) || os.IsExist(y):
return os.IsExist(x) && os.IsExist(y)
case os.IsPathSeparator(x) || os.IsPathSeparator(y):
return os.IsPathSeparator(x) && os.IsPathSeparator(y)
case os.IsPermission(x) || os.IsPermission(y):
return os.IsPermission(x) && os.IsPermission(y)
}
// Default to saying that errors are equal
return true
}) As you can imagine, the set of possible errors in Go is infinite, so it does not make sense for the |
Awesome. Thanks! |
Does this library currently support comparisons of the error type?
I tried playing around with
AllowUnexported
andcmpopts.IgnoreUnexported
but, can't seem to figure out how to make work.not-working:
The text was updated successfully, but these errors were encountered: