Three shapes
1. Controller success
2. Controller error
3. Guard or middleware error
code. The second generally does not. Some framework-level errors use { statusCode, error, message } instead.
What to branch on
Use this order:- HTTP status — always present and authoritative.
code— stable when present; safe to branch on.data.status— required for endpoints that wrap a service result (version list, version restore, version delete, and file restore).message— for humans only. It is localized and may change.
if (message === "...").
Decoding example
The 5xx rule
In production, 5xx messages are sanitized. The client receives a generic message instead of a database or driver error. The original detail is logged server-side and sent to error tracking. Do not expect to diagnose a 500 from the response body. Correlate with the timestamp, route, and your request ID.Partial success
Some operations can partially succeed:- A multi-file upload returns only the first file’s result.
- A folder copy copies a subtree and reports counts.
- A batch-style operation may report per-item results.
Nested failures
File restore and version list, restore, and delete endpoints return HTTP200 with an inner service status:
response.ok will treat this as success. Check data.status for these endpoints.
Retry matrix
Error handling checklist
Check HTTP status before parsing
data.Branch on
code when present.Handle nested
data.status for version and restore endpoints.Never display raw 5xx bodies to users.
Log route templates, status, and stable codes — never secrets.