Centralized Error Handling

Business services should throw meaningful domain errors rather than constructing HTTP responses throughout the application.

The HTTP layer maps known domain errors to status codes. Unexpected errors become generic 500 responses while the complete diagnostic information is logged internally.

This separation makes services reusable outside HTTP and ensures that every endpoint follows the same error contract.

Express Error Middleware
app.use((err, req, res, next) => {
  req.log.error({ err }, 'Unhandled API error');

  if (err.code === 'USER_NOT_FOUND') {
    return res.status(404).json({
      type: 'user-not-found',
      title: 'User not found',
      status: 404
    });
  }

  res.status(500).json({
    type: 'internal-error',
    title: 'Internal Server Error',
    status: 500,
    requestId: req.id
  });
});
💡 Known application errors are translated into stable API responses while unexpected implementation details remain internal.