intermediate

Error handling

Make failures explicit, typed where useful, logged at the right boundary, and recoverable or user-facing by deliberate policy.

Make failures explicit: typed errors or result types at boundaries, meaningful messages for operators, safe user-facing copy without leaking internals. Log once at the boundary with correlation IDs; avoid catch-and-ignore. Distinguish retryable infrastructure errors from validation bugs.

Centralize mapping to HTTP status or UI toasts; domain throws semantic errors, transport translates.

On interviews: design error flow for a payment failure with retry versus fatal decline.

Common pitfalls: empty catch blocks, stringly-typed errors, double logging, and exposing stack traces to users.

The trade-off is verbose error types versus debuggability and consistent UX.

Checklist:

  • Semantic errors in domain layer.
  • Translate at IO boundaries.
  • Log with context; never swallow silently.