Error Handling
Error handling in Go (Golang) is a fundamental part of writing robust and reliable programs. Unlike many other languages that use exceptions, Go uses a simple, explicit, and lightweight approach based on returning error values.
The error
Type
In Go, errors are represented by the built-in error
type, which is an interface:
type error interface {
Error() string
}
Any type that implements the Error()
method with the signature Error() string
satisfies the error
interface.
Returning and Checking Errors
Functions that can fail typically return an error as the last return value. The caller is responsible for checking this value:
func readFile(filename string) ([]byte, error) {
// ...
}
data, err := readFile("data.txt")
if err != nil {
// handle the error
log.Fatal(err)
}
// use data
Creating Errors
We can create errors using the errors.New
function or fmt.Errorf
for formatted errors:
import (
"errors"
"fmt"
)
err1 := errors.New("something went wrong")
err2 := fmt.Errorf("failed to open file: %s", filename)
Custom Error Types
For more context, we can define custom error types:
type MyError struct {
Code int
Message string
}
func (e *MyError) Error() string {
return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}
// Usage
return &MyError{Code: 404, Message: "Not Found"}
Error Wrapping and Unwrapping
Go 1.13 introduced error wrapping with %w
in fmt.Errorf
and the errors.Is
and errors.As
functions for error inspection:
wrappedErr := fmt.Errorf("operation failed: %w", err)
if errors.Is(wrappedErr, err) {
// err is in the error chain
}
Sentinel Errors
Sometimes, we define package-level variables for common errors (sentinel errors):
var ErrNotFound = errors.New("not found")
func findItem(id int) error {
if id == 0 {
return ErrNotFound
}
return nil
}
if err == ErrNotFound {
// handle not found
}
Panic and Recover
Go does have a panic/recover mechanism, but it is reserved for truly exceptional situations (e.g., unrecoverable errors):
func mayPanic() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("something bad happened")
}