In Go, the standard approach to error handling is by returning a value of type error from functions. Unlike languages with exceptions, in Go exceptions (panic, recover) are used only for truly exceptional situations; for business logic, regular errors should be used.
The classic way:
func doSomething() error { // ... return nil // or errors.New("some error") } err := doSomething() if err != nil { // handle error }
You can create custom error types for more detailed analysis:
type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "not found"}
Typical check for a specific error:
if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // handle 404 error }
Can you compare error to nil using == in Go?
Answer: Yes, you can and should do this to check for the absence of an error. However, it's important to remember: if the error has been wrapped or created using errors containing nil inside structs, then the comparison might be incorrect. For example:
var err error = (*MyError)(nil) fmt.Println(err == nil) // false!
An error is not equal to nil because the interface is not nil if its type is not nil, even if the value inside is nil.
Story
A microservice was logging errors by comparing to nil. One developer returned a typed error like (*MyError)(nil), not noticing that this is not equivalent to nil (the interface is not nil). As a result, error handling stopped working, and many false alerts were logged.
Story
In a project, instead of passing errors along the chain, they used panic for all errors, considering this a "clean" way. This led to the application crashing on every invalid user input, as panic/recover are not meant for streaming business logic.
Story
An error was wrapped several times using fmt.Errorf("some: %w", err), and when checking for a specific error type, they performed a regular comparison instead of using errors.Is and errors.As. This led to business logic not reacting to custom error types, even though they were indeed present within the wrapped error.