पाठ 13 / 26

Designing Errors

Messages and types callers can use.

Sentinels, types and handling once

Choose how callers will use an error: a sentinel (var ErrNotFound = errors.New(...)) for conditions they check, a custom type when they need details (a field name, a retry-after duration), or a plain wrapped error when they only log it. Error strings are lowercase without trailing punctuation, because they are combined. Handle each error once: either return it (with context) or log and handle it, but not both, to avoid duplicate logs.

Error design choices

Pick based on what the caller needs.

caller needs to...                         use
check a specific condition                  sentinel: var ErrNotFound = errors.New("not found")
read details (field, code, retry time)      custom type implementing Error()
just report it                              fmt.Errorf("load config: %w", err)
stop the program on an impossible state     panic (programmer error only)

Log at the top, wrap below

Lower layers wrap and return; the outermost handler (request, job) logs once with full context.

त्वरित जाँच: Why avoid both logging and returning the same error?

  • Returning errors is forbidden
  • It produces duplicate log entries as the error moves up
  • Logs cannot contain errors
  • It changes the error type
Answer

It produces duplicate log entries as the error moves up — Handle an error once.