How do you handle errors and return consistent error responses in a Web API?

Web API & REST API Design Intermediate 2–3 Yrs3–5 Yrs Conceptual 1 min read

Quick Answer

Use one central exception-handling middleware (or IExceptionHandler in .NET 8) that catches unhandled exceptions and returns a consistent ProblemDetails body (RFC 7807) with the right status code. Let [ApiController] auto-return 400 for validation. Never leak stack traces in production; log the detail server-side with a correlation id.

I have one place that handles errors — exception-handling middleware, or IExceptionHandler in .NET 8 — rather than try/catch in every controller. It maps known exception types to status codes and returns a ProblemDetails body so every error looks the same to the client: type, title, status, detail and a trace id that ties back to the server log. Validation is handled for free by [ApiController], which returns a 400 with the field errors. Expected outcomes like “not found” or “conflict” I return explicitly from the action. And in production the response never contains a stack trace — that goes in the log.

  • Validation errors — [ApiController] turns invalid ModelState into a 400 with a ValidationProblemDetails body automatically.
  • Expected domain errors — return them explicitly: NotFound(), Conflict(), UnprocessableEntity().
  • Unexpected exceptions — a single handler maps exception types to status codes (e.g. NotFoundException → 404, everything else → 500) and produces a ProblemDetails.
  • Shape — { type, title, status, detail, instance, traceId }. Include a traceId so support can find the log entry.
  • Don't wrap every action in try/catch; that's what the middleware is for.