panic — immediate runtime failure that stops execution. error — expected failure returned as a value.
Panic behavior:
recover().recover(), crashes program.1// Panic for invariant violations2func Must(s string) Config {3 cfg, err := Parse(s)4 if err != nil {5 panic("invalid config: " + err.Error())6 }7 return cfg8}910// Recover at goroutine boundary11func safeGo(fn func()) {12 go func() {13 defer func() {14 if r := recover(); r != nil {15 log.Printf("panic recovered: %v", r)16 }17 }()18 fn()19 }()20}
Error behavior:
1// Idiomatic error handling2func readJSON(path string, v interface{}) error {3 data, err := os.ReadFile(path)4 if err != nil {5 return fmt.Errorf("reading %s: %w", path, err)6 }7 if err := json.Unmarshal(data, v); err != nil {8 return fmt.Errorf("parsing %s: %w", path, err)9 }10 return nil11}
When to use panic:
init() failures.When to use error:
Common mistakes:
errors.Is/errors.As.log.Fatal instead of returning error.