error — a Go interface for expected failures (value-based). Exception — a concept from other languages (Java/C++) not directly present in Go (Go uses panic/recover).
The error interface:
1type error interface {2 Error() string3}
Any type with Error() string method satisfies this interface.
Creating errors:
1// Simple sentinel errors2var (3 ErrNotFound = errors.New("not found")4 ErrUnauthorized = errors.New("unauthorized")5)67// Custom error types8type ValidationError struct {9 Field string10 Message string11}1213func (e *ValidationError) Error() string {14 return fmt.Sprintf("field %s: %s", e.Field, e.Message)15}1617// Wrapping errors18func loadConfig(path string) (*Config, error) {19 data, err := os.ReadFile(path)20 if err != nil {21 return nil, fmt.Errorf("reading config: %w", err)22 }23 // ...24}
Error handling:
1// errors.Is for sentinel errors (works with wrapping)2if errors.Is(err, ErrNotFound) {3 // handle not found4}56// errors.As for custom error types7var valErr *ValidationError8if errors.As(err, &valErr) {9 fmt.Println(valErr.Field)10}1112// Type switch13switch e := err.(type) {14case *ValidationError:15 // handle validation16case *os.PathError:17 // handle file error18}
Go philosophy:
Common mistakes:
== instead of errors.Is().