I have an error value which when printed on console gives me Token is expired
How can I compare it with a specific error value? I tried this but it did not work:
if err == errors.New("Token is expired") { log.Printf("Unauthorised: %s\n", err) }
Using the Is function of errors package – https://golang.org/pkg/errors/ . Using Is function is preferable to using the equality operator because it checks for equality by unwrapping the first error sequentially and matches it with the target error at each step of unwrap.
If we want to check if a given error matches another specific error, we need to use Is() function from the errors package. If we are interested in whether the error is of a given type, we should call the As() function.
It does not matter that the error is wrapped. A simple comparison if err == ErrorInternal would give false in this case, so it is generally a better idea to use the errors.Is() function to compare errors equality. Then, we unwrap the error using the errors. Unwrap() and print it to the standard output.
Go's built-in errors don't contain stack traces, nor do they support conventional try / catch methods to handle them. Instead, errors in Go are just values returned by functions, and they can be treated in much the same way as any other datatype - leading to a surprisingly lightweight and simple design.
Declaring an error, and comparing it with '==
' (as in err == myPkg.ErrTokenExpired
) is no longer the best practice with Go 1.13 (Q3 2019)
The release notes mentions:
Go 1.13 contains support for error wrapping, as first proposed in the Error Values proposal and discussed on the associated issue.
An error
e
can wrap another errorw
by providing anUnwrap
method that returnsw
.
Bothe
andw
are available to programs, allowinge
to provide additional context tow
or to reinterpret it while still allowing programs to make decisions based onw
.To support wrapping,
fmt.Errorf
now has a%w
verb for creating wrapped errors, and three new functions in theerrors
package (errors.Unwrap
,errors.Is
anderrors.As
) simplify unwrapping and inspecting wrapped errors.
So the Error Value FAQ explains:
You need to be prepared that errors you get may be wrapped.
If you currently compare errors using
==
, useerrors.Is
instead.
Example:if err == io.ErrUnexpectedEOF
becomes
if errors.Is(err, io.ErrUnexpectedEOF)
- Checks of the form if
err != nil
need not be changed.- Comparisons to
io.EOF
need not be changed, becauseio.EOF
should never be wrapped.If you check for an error type using a type assertion or type switch, use
errors.As
instead. Example:if e, ok := err.(*os.PathError); ok
becomes
var e *os.PathError if errors.As(err, &e)
Also use this pattern to check whether an error implements an interface. (This is one of those rare cases when a pointer to an interface is appropriate.)
Rewrite a type switch as a sequence of
if-elses
.
This answer is for Go 1.12 and earlier releases.
Define an error value in a library
package fruits var NoMorePumpkins = errors.New("No more pumpkins")
Do not create errors with errors.New
anywhere in the code but return the predefined value whenever error occurs and then you can do the following:
package shop if err == fruits.NoMorePumpkins { ... }
See io
package errors for reference.
This can be improved by adding methods to hide the check implementation and make the client code more immune to changes in fruits
package.
package fruits func IsNoMorePumpkins(err error) bool { return err == NoMorePumpkins }
See os
package errors for reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With