Node.js › Error Handling
What is the difference between a 4xx and 5xx HTTP status code from an error-handling perspective, and how should a Node.js API decide which to return?
AdvancedAnswer
4xx status codes indicate the client made a mistake (invalid input, missing authentication, requesting a nonexistent resource) -- these are typically operational errors that should include a clear, actionable message helping the client fix their request. 5xx status codes indicate a server-side failure (an unexpected exception, a database outage) -- the specific internal details generally should NOT be exposed to the client (to avoid leaking implementation details or security-sensitive information), typically returning a generic 'Internal Server Error' message while logging full details server-side for debugging.
app.use((err, req, res, next) => {
if (err.isOperational) {
return res.status(err.statusCode || 400).json({ error: err.message }); // safe to show details
}
logger.error('Unexpected error:', err); // log full details internally
res.status(500).json({ error: 'Internal server error' }); // generic message to the client
});Real-world example An API returns a specific 400 error with 'Email is already registered' for a validation failure (safe, helpful to show), but for an unexpected database connection error, returns only a generic 500 'Internal server error' to the client while logging the full stack trace and connection details internally for the engineering team.