javascript 51 lines · 8 steps

Centralized error handling in Express

A custom error class plus a catch-all middleware turn scattered failures into consistent, well-logged JSON responses.

Explained by highlit
1const logger = require('./logger');
2 
3class AppError extends Error {
4 constructor(message, statusCode = 500, details = null) {
5 super(message);
6 this.statusCode = statusCode;
7 this.details = details;
8 this.isOperational = true;
9 Error.captureStackTrace(this, this.constructor);
10 }
11}
12 
13function notFoundHandler(req, res, next) {
14 next(new AppError(`Route ${req.method} ${req.originalUrl} not found`, 404));
15}
16 
17function errorHandler(err, req, res, next) {
18 if (res.headersSent) {
19 return next(err);
20 }
21 
22 let statusCode = err.statusCode || 500;
23 let message = err.message || 'Internal Server Error';
24 
25 if (err.name === 'ValidationError') {
26 statusCode = 422;
27 } else if (err.name === 'JsonWebTokenError' || err.name === 'TokenExpiredError') {
28 statusCode = 401;
29 message = 'Invalid or expired token';
30 } else if (err.code === '23505') {
31 statusCode = 409;
32 message = 'Resource already exists';
33 }
34 
35 const meta = { method: req.method, path: req.originalUrl, statusCode };
36 if (statusCode >= 500) {
37 logger.error({ ...meta, stack: err.stack }, message);
38 } else {
39 logger.warn(meta, message);
40 }
41 
42 res.status(statusCode).json({
43 error: {
44 message,
45 ...(err.details ? { details: err.details } : {}),
46 ...(process.env.NODE_ENV === 'development' ? { stack: err.stack } : {}),
47 },
48 });
49}
50 
51module.exports = { AppError, notFoundHandler, errorHandler };
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A single error-handling middleware keeps status-code and response shape logic in one auditable place.
  2. 2Distinguishing operational errors and mapping library error signatures to HTTP codes prevents leaking raw internals to clients.
  3. 3Logging severity and response detail should scale with status code and environment to aid debugging without exposing stack traces in production.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Centralized error handling in Express — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code