Careeroza
Consistent Error Format
Design One Error Shape
Frontend and mobile developers love APIs where every error looks the same. A common shape:
{
"success": false,
"error": {
"statusCode": 422,
"code": "OUT_OF_STOCK",
"message": "Only 2 left for product 7",
"details": { "productId": 7, "available": 2 },
"path": "/api/orders",
"requestId": "0b9a5c1e"
},
"timestamp": "2026-01-15T10:00:00.000Z"
}- code: a stable machine-readable string the app can switch on (messages may change or be translated).
- message: human-readable, safe to show.
- details: optional extra data (validation errors per field).
- requestId: links the error to server logs.
Normalising Any Error
Example
The function at the heart of such a filter: accept anything that was thrown and always produce the same shape.
type HttpLike = { status: number; response: string | { message?: string | string[]; code?: string } };
const isHttp = (e: unknown): e is HttpLike => typeof e === 'object' && e !== null && 'status' in e && 'response' in e;
function normalise(e: unknown, path: string) {
let statusCode = 500;
let code = 'INTERNAL';
let message: string | string[] = 'Internal server error';
if (isHttp(e)) {
statusCode = e.status;
if (typeof e.response === 'string') message = e.response;
else {
message = e.response.message ?? message;
code = e.response.code ?? (Array.isArray(message) ? 'VALIDATION_FAILED' : 'HTTP_' + statusCode);
}
if (code === 'INTERNAL') code = 'HTTP_' + statusCode;
}
return { success: false, error: { statusCode, code, message, path } };
}
console.log(JSON.stringify(normalise({ status: 404, response: 'Product 999 not found' }, '/products/999')));
console.log(JSON.stringify(normalise({ status: 400, response: { message: ['price must be a positive number'] } }, '/products')));
console.log(JSON.stringify(normalise({ status: 422, response: { code: 'OUT_OF_STOCK', message: 'Only 2 left' } }, '/orders')));
console.log(JSON.stringify(normalise(new Error('connection refused'), '/orders')));Output
{"success":false,"error":{"statusCode":404,"code":"HTTP_404","message":"Product 999 not found","path":"/products/999"}}
{"success":false,"error":{"statusCode":400,"code":"VALIDATION_FAILED","message":["price must be a positive number"],"path":"/products"}}
{"success":false,"error":{"statusCode":422,"code":"OUT_OF_STOCK","message":"Only 2 left","path":"/orders"}}
{"success":false,"error":{"statusCode":500,"code":"INTERNAL","message":"Internal server error","path":"/orders"}}