Error Interfaces

112 views
Skip to first unread message

Nikhilesh Susarla

unread,
Nov 5, 2022, 12:29:35 PM11/5/22
to golang-nuts

Same interface comparison 


Why is the equals too still returning false? 

Any more details on this? 

Thank you

Axel Wagner

unread,
Nov 5, 2022, 12:33:00 PM11/5/22
to Nikhilesh Susarla, golang-nuts
Every invocation of `errors.New` returns a new unique error value, even if the same error text is used.
That is intentional. It would be confusing, if package A chose the same error sentinel text as package B and suddenly their sentinels compare as equal.
If you want error identity between values, you have to actually copy the error value (or implement your own, which may very well not do it this way).

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ee3d53d3-d3c8-4a3b-801a-af6060316e3an%40googlegroups.com.

Axel Wagner

unread,
Nov 5, 2022, 12:33:54 PM11/5/22
to Nikhilesh Susarla, golang-nuts
Oh and this behavior is documented, of course: https://pkg.go.dev/errors#New

Nikhilesh Susarla

unread,
Nov 5, 2022, 12:39:09 PM11/5/22
to Axel Wagner, golang-nuts
Oh I see. 
What is the best way to compare errors? 
Here in the above example I can do e.Error() == ErrNotFound.Error() // which returns true
Is there any other way rather than string comparison ?

Thank you

Sean Foley

unread,
Nov 5, 2022, 12:58:44 PM11/5/22
to Nikhilesh Susarla, Axel Wagner, golang-nuts
If the error is created by your code, then just reuse the same one.


If the error is created by code other than your own, and that code does not reuse the same error, then compare strings.


Nikhilesh Susarla

unread,
Nov 5, 2022, 1:00:49 PM11/5/22
to Sean Foley, Axel Wagner, golang-nuts
The error is coming from other package. So, then have to compare strings. I guess

Axel Wagner

unread,
Nov 5, 2022, 1:07:35 PM11/5/22
to Nikhilesh Susarla, Sean Foley, golang-nuts
To be clear: The recommendation is *not* to compare strings. The recommendation is to compare errors by identity and not consider errors created by different packages to be equal.

If you desperately need your error to be considered "the same" as another, the most correct way would be to implement `Is(other error) bool`, e.g.

type notQuiteEOF struct {}
func (notQuiteEOF) Error() string {
    return "not quite EOF, but almost"
}
func (notQuiteEOF) Is(other error) bool {
    return other == io.EOF
}

This allows errors to be considered "the same" under `errors.Is`, while not actually being the same and it's probably the recommended mechanism to "imitate" an error from a different package.

Nikhilesh Susarla

unread,
Nov 6, 2022, 12:43:26 AM11/6/22
to Axel Wagner, Sean Foley, golang-nuts
Thank you for the clarification. 

Jason Phillips

unread,
Nov 6, 2022, 2:12:25 AM11/6/22
to golang-nuts
Also note that in your original example you created two unique pointers to your error type. Even if the errors created using errors.New were equal, your example would never return true.

Reply all
Reply to author
Forward
0 new messages