← O-Reilly Learning Go

Errors

GolangErrors

Sentinel Errors

Sentinel errors are one of the few variables that are declared at the package level. By convention, their names start with Err. They should be treated as read-only; there’s no way for the Go compiler to enforce this, but it is a programming error to change their value.

package mypkg 
const ( 
	ErrFoo = consterr.Sentinel("foo error") 
	ErrBar = consterr.Sentinel("bar error") 
	)

If we use constant error across the packages, two errors would be equal if the their error strings are equal.
An error created with errors.New is equal only to itself or to variables explicitly assigned its value.

Errors Are Values

If we return a custom error via a error interface, there is one thing to notice.
Which is when we return an empty custom error, if we pass the empty custom error to error interface, the Go would automatically put the custom error type in the type of the error interface.
interface has (type,value)
Thus if we check == nil, that will be false. As both types and values are not nil( interface is nill when both type and value are nils).

When using custom errors, never define a variable to be of the type of your custom error. Either explicitly return nil when no error occurs or define the variable to be of type error

Is and As

The errors.Is function returns true if any error in the error tree matches the provided sentinel error.
Another use for defining your own Is method is to allow comparisons against errors that aren’t identical instances.

The errors.As function allows you to check whether a returned error (or any error it wraps) matches a specific type.

In short:

Wrapping Error with defer

In some cases, we can wrap error with defer without wrapping for every single line.

Panic and Recover

If there is a panic in a goroutine other than the main goroutine, the chain of defers ends at the function used to launch the goroutine. A program exits if any goroutine panics without being recovered.

Reserve panics for fatal situations and use recover as a way to gracefully handle these situations.

The reason you don’t rely on panic and recover is that recover doesn’t make clear what could fail. It just ensures that if something fails, you can print out a message and continue. Idiomatic Go favors code that explicitly outlines the possible failure conditions over shorter code that handles anything while saying nothing.

Getting a Stack Trace from an Error

We can use error wrapping to build the call stack by hand.
By default, the stack trace is not printed out.If you want to see the stack trace, use fmt.Printf and the verbose output verb (%+v).