Express Error Handling Mechanism
In Express, error handling middleware is a special type of middleware function with four parameters: err, req, res, and next. This type of middleware is specifically designed to handle errors that occur during request processing.
Implementing Error Handling Middleware
Basic Error Handling
// Error handling middleware
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});This code defines an error handling middleware that captures all unhandled errors, returns a 500 status code response, and logs the error stack to the console.
Custom Error Class
To better control error messages and status codes, you can define custom error classes.
class CustomError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
try {
throw new CustomError('Invalid input', 400);
} catch (err) {
next(err);
}In this example, we define a CustomError class that extends the native Error class and adds a statusCode property. When throwing this error, we can specify the error message and HTTP status code.
Unified Error Response
To provide consistent error responses, you can create a unified error handling function.
function sendErrorResponse(err, res) {
const statusCode = err.statusCode || 500;
const message = err.message || 'Internal Server Error';
res.status(statusCode).json({
error: {
message,
status: statusCode
}
});
}
// Error handling middleware
app.use(function(err, req, res, next) {
sendErrorResponse(err, res);
});This code defines a sendErrorResponse function that generates a JSON-formatted error response based on the error object’s statusCode and message properties.
Error Logging
In a production environment, simply logging error stacks to the console is insufficient. Professional logging tools like Winston or Bunyan should be used to record errors.
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log' })
]
});
app.use(function(err, req, res, next) {
logger.error(err.stack);
sendErrorResponse(err, res);
});Here, the Winston logging library is used to record error stacks to a file.
Exception Handling
In addition to standard error handling, attention must be paid to errors in asynchronous code. For example, uncaught exceptions in Promise or async/await code can cause the application to crash.
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});This code registers a listener to capture unhandled Promise rejection events.



