16. Error Handling Discipline
16. Error Handling Discipline
How your API handles errors is just as important as how it handles success. Sloppy error handling leaks implementation details, breaks client integrations, and makes debugging nearly impossible.
Map Exceptions to Consistent Error Envelopes
Every error, regardless of where it originates in your application stack, must arrive at the client in the same envelope shape (see topic 6). Write a global exception handler that catches unhandled errors and transforms them into your standard error response:
{
"error": {
"code": 500,
"message": "An unexpected error occurred.",
"request_id": "req_a1b2c3d4"
}
}
This keeps client-side error handling simple: parse one shape, branch on the code.
Never Leak Stack Traces in Production
Stack traces, SQL queries, and internal file paths are invaluable during development. In production, they hand an attacker a detailed map of your application internals. Disable verbose error output in production environments and ensure your global exception handler strips any internal details before sending the response.
Add a Request or Correlation ID
Every response — success or error — should include a unique request identifier. This ID ties a single request together across your logs, traces, and monitoring dashboards:
X-Request-ID: req_a1b2c3d4
When a client reports a problem, they can hand you this ID and you can find the exact request in your logs in seconds. Include the same ID in the error response body so that even if the client does not inspect headers, the correlation ID is available.
Log Errors Server-Side
Every 5xx response must produce a log entry with the full stack trace, the request details, and the correlation ID. For 4xx errors, log at a lower severity — they are usually the client's responsibility — but still record them so you can spot patterns (a flood of 401s may indicate a credential issue; repeated 404s may reveal a broken client).
Be Specific Where You Can, Generic Where You Must
A 404 response can safely say "Product not found." A 500 response should say nothing beyond "An unexpected error occurred." The distinction is deliberate: client errors deserve enough detail for the developer to fix their request; server errors must not reveal how to exploit your internals.