Effective Error Creation in Go
Error handling is a crucial aspect of writing robust Go code. Creating informative and useful errors is key to effective error handling. This article explores various methods of error creation in Go.
Basic Error Creation
The simplest way to create an error is using errors.New()
:
import "errors"
err := errors.New("something went wrong")
Formatted Errors
For more detailed errors, use fmt.Errorf()
:
import "fmt"
name := "file.txt"
err := fmt.Errorf("failed to open file: %s", name)
Custom Error Types
For more complex scenarios, create custom error types:
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
err := &ValidationError{Field: "email", Message: "invalid format"}
Error Wrapping (Go 1.13+)
Wrap errors to add context while preserving the original error:
originalErr := errors.New("database connection failed")
wrappedErr := fmt.Errorf("query failed: %w", originalErr)
// Later, you can unwrap:
fmt.Println(errors.Unwrap(wrappedErr))
Sentinel Errors
For specific error conditions that callers might want to check for:
var ErrNotFound = errors.New("item not found")
func FindItem(id string) (*Item, error) {
// ...
return nil, ErrNotFound
}
// Usage:
if err == ErrNotFound {
// Handle not found case
}
Error Handling Example
func processFile(name string) error {
f, err := os.Open(name)
if err != nil {
return fmt.Errorf("failed to open %s: %w", name, err)
}
defer f.Close()
// Process file...
return nil
}
Effective error creation in Go involves choosing the right method based on the complexity of the error and the information you need to convey. By following these practices, you can create clear, informative, and useful errors in your Go programs.