Error Handling
Standard error response structure
- Use one envelope everywhere: e.g.
{ "error": { "code", "message", "details", "requestId" } }.
- Codes are stable machine strings (
order_not_found); messages can change for humans.
- Include field-level errors for validation (
details: [{ "field": "email", "issue": "invalid" }]).
Meaningful error messages
- Tell the client what to do next without leaking secrets or internal stack traces.
- Avoid vague “Something went wrong” for 4xx; be specific enough to fix the request.
- For 5xx, keep user-facing text generic while logging rich context server-side.
Error codes vs HTTP status confusion
- HTTP status describes transport-level outcome; body
code describes domain outcome.
- Do not return 200 OK with
{ success: false } for failures; intermediaries and clients will mis-handle it.
- Align retry behavior: 429/503 may retry; 400/404 usually should not blindly retry the same payload.
Debugging-friendly responses
- Always return a request/correlation id clients can quote in support tickets.
- In non-prod, optional debug blocks help; gate them strictly in production.
- Log the same id across services for distributed traces.