Skip to main content

API-001: Use Appropriate HTTP Status Codes

AttributeValue
CategoryAPI Design
Default Severitywarning
Applicable FilesController files (*.controller.ts, *.handler.ts)

Why It Exists (Rationale)​

HTTP status codes represent the universal contract of the web. When backend endpoints catch errors and return HTTP 200 with { "error": "something failed" }:

  • Client SDKs and frontend error boundaries fail to intercept failures.
  • API gateways, proxies, and load balancers cannot report error metrics.
  • Monitoring alerts (e.g. 5xx rates) remain blind to ongoing production outages.

Bad Example​

try {
await orderService.process(req.body);
} catch (err) {
// ❌ Masks error behind HTTP 200
return res.status(200).json({ error: "Order failed", details: err.message });
}

Good Example​

try {
const order = await orderService.process(req.body);
return res.status(200).json(order);
} catch (err) {
// ✅ Returns semantically correct 4xx or 5xx code
return res.status(500).json({
error: { code: "ORDER_FAILED", message: "Failed to process order" },
});
}

How It's Detected​

ArchStandards scans AST nodes inside catch blocks or error branches in controller files, checking for .status(200) or .json({ error: ... }) returned with default 200 status.