typescriptintermediate
Express Error Handling Middleware
Centralized error handling in Express with custom error classes, async wrapper, and structured responses.
typescriptPress ⌘/Ctrl + Shift + C to copy
import type { Request, Response, NextFunction, RequestHandler } from 'express';
// Custom error classes
class AppError extends Error {
constructor(
public statusCode: number,
message: string,
public code?: string,
) {
super(message);
this.name = 'AppError';
}
}
class NotFoundError extends AppError {
constructor(resource: string, id?: string) {
super(404, id ? `${resource} '${id}' not found` : `${resource} not found`, 'NOT_FOUND');
}
}
class ValidationError extends AppError {
constructor(public errors: { field: string; message: string }[]) {
super(400, 'Validation failed', 'VALIDATION_ERROR');
}
}
class UnauthorizedError extends AppError {
constructor(message = 'Unauthorized') {
super(401, message, 'UNAUTHORIZED');
}
}
// Async handler wrapper
const asyncHandler = (fn: (req: Request, res: Response, next: NextFunction) => Promise<any>): RequestHandler =>
(req, res, next) => fn(req, res, next).catch(next);
// Error handler middleware (must be last)
function errorHandler(err: Error, req: Request, res: Response, _next: NextFunction) {
console.error(`[${req.method}] ${req.path}:`, err.message);
if (err instanceof ValidationError) {
return res.status(400).json({
error: { code: err.code, message: err.message, details: err.errors },
});
}
if (err instanceof AppError) {
return res.status(err.statusCode).json({
error: { code: err.code, message: err.message },
});
}
// Unexpected errors — don't leak internals
res.status(500).json({
error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' },
});
}
// Usage in routes
// app.get('/users/:id', asyncHandler(async (req, res) => {
// const user = await db.findUser(req.params.id);
// if (!user) throw new NotFoundError('User', req.params.id);
// res.json(user);
// }));
// app.use(errorHandler);
export { AppError, NotFoundError, ValidationError, UnauthorizedError, asyncHandler, errorHandler };Sponsored
Railway
Use Cases
- API error standardization
- Async route error handling
- Structured error responses
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptbeginner
Async Error Handler Wrapper
Higher-order function that wraps async Express route handlers and forwards rejected promises to error middleware.
Best for: Express route error handling
#express#async
typescriptintermediate
JWT Verify Middleware
Express middleware that verifies JWT tokens from the Authorization header and attaches the decoded payload to the request.
Best for: REST API authentication
#jwt#express
typescriptintermediate
In-Memory Rate Limiter for Express
Token bucket rate limiter middleware for Express with configurable window and max requests per IP.
Best for: API abuse prevention
#express#rate-limit
typescriptbeginner
Express Zod Request Validation
Validate Express request body, params, and query with Zod schemas via reusable middleware.
Best for: API input validation
#express#zod