error — a Go interface type that represents an expected failure. Exception — not a Go concept (languages like Java/C++ use try-catch; Go uses panic/recover).
The error interface:
1type error interface {2 Error() string3}
Error() string method implements this interface.Creating custom errors:
1// Using errors.New for simple errors2var ErrNotFound = errors.New("resource not found")34// Custom error type for structured errors5type ValidationError struct {6 Field string7 Message string8}910func (e *ValidationError) Error() string {11 return fmt.Sprintf("validation error on %s: %s", e.Field, e.Message)12}1314// Wrapping errors with context15func readConfig(path string) (*Config, error) {16 data, err := os.ReadFile(path)17 if err != nil {18 return nil, fmt.Errorf("reading config: %w", err) // wrap19 }20 // ...21}
Error checking patterns:
1// Direct comparison2if err == ErrNotFound {3 // handle specific error4}56// Errors.Is for wrapped errors7if errors.Is(err, ErrNotFound) {8 // works even if wrapped with fmt.Errorf9}1011// errors.As for custom error types12var valErr *ValidationError13if errors.As(err, &valErr) {14 fmt.Println(valErr.Field)15}
Go philosophy on errors:
Common mistakes:
result, _ := doSomething()).== instead of errors.Is() (doesn't work with wrapped errors).panic where an error return would be appropriate.