panic — immediate runtime failure that stops normal execution. error — expected failure returned as a value for graceful handling.
Panic mechanics:
recover().recover(), crashes program with stack trace.1// Panic for invariant violations2func MustParse(s string) Config {3 cfg, err := Parse(s)4 if err != nil {5 panic("invalid config: " + err.Error())6 }7 return cfg8}910// Recover in goroutine boundary11func safeWorker() {12 defer func() {13 if r := recover(); r != nil {14 log.Printf("worker panic: %v\n%s", r, debug.Stack())15 }16 }()17 // ... worker logic18}
Error mechanics:
1// Idiomatic error handling2func FindUser(id int) (*User, error) {3 row := db.QueryRow("SELECT * FROM users WHERE id=$1", id)4 var user User5 if err := row.Scan(&user.ID, &user.Name); err != nil {6 if errors.Is(err, sql.ErrNoRows) {7 return nil, fmt.Errorf("user %d: %w", id, ErrNotFound)8 }9 return nil, fmt.Errorf("querying user %d: %w", id, err)10 }11 return &user, nil12}
When to use panic:
init() failures.When to use error:
Common mistakes:
errors.Is/errors.As.log.Fatal instead of returning error.