Error Handling in Go
Go takes a unique approach to error handling. Instead oftry/catch exceptions found in languages like Java or Python, Go treats errors as values. This forces developers to handle errors explicitly where they occur, leading to more robust and predictable software.
The error Interface
In Go, an error is anything that implements the built-in error interface:
Basic Error Handling
Functions often return anerror as the last return value.
Creating Errors
You can create simple errors usingerrors.New or fmt.Errorf.
Custom Error Types
Sinceerror is an interface, you can create custom structs that implement it to provide more context.
Wrapping and Unwrapping Errors
Go 1.13 introduced error wrapping, allowing you to add context to an error while preserving the original error. This creates an “error chain” that can be inspected programmatically.Wrapping
Use the%w verb with fmt.Errorf to wrap an error:
Unwrapping (errors.Is and errors.As)
When you have a wrapped error, you need special functions to inspect the chain:
errors.Is(err, target): Checks if any error in the chain matches the target error.errors.As(err, &target): Finds the first error in the chain that matches the target type and assigns it.
err == io.EOF) only works for the outermost error. errors.Is traverses the entire chain.
Panic and Recover
Go has a mechanism for exceptional conditions calledpanic. It should be used sparingly, mostly for unrecoverable errors (like nil pointer dereferences or invariant violations).
Panic
panic stops the ordinary flow of control and begins panicking.
Recover
recover is a built-in function that regains control of a panicking goroutine. It is only useful inside a deferred function.
Best Practices
- Don’t Ignore Errors: Always check the
errreturn value. Use_only if you are absolutely sure the error is irrelevant. - Add Context: Wrap errors to provide “stack trace”-like context (e.g., “loading config: parsing json: syntax error”).
- Avoid Panic: Use errors for normal control flow. Reserve panic for truly exceptional, unrecoverable states.
Summary
- Errors are values in Go, implementing the
errorinterface. - Handle errors explicitly using
if err != nil. - Use
fmt.Errorfwith%wto wrap errors with context. - Use
errors.Isanderrors.Asto inspect wrapped errors. panicandrecoverare for exceptional circumstances, not normal flow control.