How To Create Custom Error Handler Middleware in Express?
Last Updated :
20 Feb, 2025
In ExpressJS there is a built-in class named CustomError which is basically used to create an error of your choice. in this article, we will see how with the use of this CustomError class we can create a custom error handler middleware in ExpressJS.
What is a CustomError Handler?
A custom error handler in Express is a special middleware function designed to handle errors in a centralized way. It takes four parameters: (err, req, res, next), where err is the error object. When an error occurs in a route or middleware, it can be passed to the error handler using next(err).
The error handler then processes the error, sets an appropriate status code, and sends a consistent response to the client. This approach improves error management by preventing crashes, simplifying debugging, and ensuring uniform error messages across the application.
To make a custom error middleware first we need to know about the Error.captureStackTrace function in the custom error class.
Error.captureStackTrace in CustomError class
Error.captureStackTrace(this) in a CustomError class helps record where the error happened while removing unnecessary details like the constructor call. This makes the stack trace clearer and easier to debug.
1. Stack without Error.StackTrace
This code defines a CustomError class that extends JavaScript's built-in Error and captures a clean stack trace when an error is thrown. It then simulates a function call chain leading to an error.
JavaScript
class CustomError extends Error {
constructor(message) {
super(message)
this.name = 'Custom Error'
Error.captureStackTrace(this)
}
}
function one() {
two()
}
function two() {
three()
}
function three() {
throw new CustomError('Something went wrong')
}
try {
one()
}
catch (error) {
console.error(error.stack)
}
Output
Stack without Error.StackTrace- The constructor function (new CustomError) is visible in the call stack because Error.captureStackTrace(this) is used with only one parameter (this), meaning it records the full stack trace, including the constructor.
- The one(), two(), and three() functions call each other, forming a function call chain.
- The three() function throws a CustomError, which gets caught in the try...catch block.
- The catch block logs the error's stack trace, showing the exact sequence of function calls leading to the error, including the constructor, because no second argument was provided to exclude it.
2. Stack with Error.StackTrace
This code defines a CustomError class that extends JavaScript’s Error and removes the constructor from the stack trace using Error.captureStackTrace(this, this.constructor). It then triggers an error through a function call chain.
JavaScript
class CustomError extends Error {
constructor(message) {
super(message)
this.name = 'Custom Error'
Error.captureStackTrace(this, this.constructor)
}
}
function one() {
two()
}
function two() {
three()
}
function three() {
throw new CustomError('Something went wrong')
}
try {
one()
}
catch (error) {
console.error(error.stack)
}
Output
Stack with Error.StackTrace- The constructor function (new CustomError) is hidden in the call stack because Error.captureStackTrace(this, this.constructor) removes it.
- The functions one(), two(), and three() call each other sequentially, creating a function call chain.
- The three() function throws a CustomError, which gets caught in the try...catch block.
- The catch block logs the error’s stack trace, showing only the function calls leading to the error, but excluding the constructor, making the trace cleaner.
Now lets make a CustomError Handler in Express
This code sets up an Express server that uses a CustomError class to handle errors in a structured way. It includes a route that deliberately throws an error and a global middleware to catch and respond to errors.
JavaScript
class CustomError extends Error {
constructor(statusCode, message) {
super(message);
this.statusCode = statusCode;
// Maintain proper stack trace
Error.captureStackTrace(this, this.constructor);
}
}
export default CustomError;
JavaScript
app.use(express.json());
// Sample Route that throws a Custom Error
app.get("/error-demo", (req, res, next) => {
try {
throw new CustomError(400, "This is a custom error!");
} catch (error) {
next(error); // Pass error to the error-handling middleware
}
});
// Global Error Handling Middleware
app.use((err, req, res, next) => {
const statusCode = err.statusCode || 500;
const message = err.message || "Internal Server Error";
res.status(statusCode).json({
success: false,
error: {
statusCode,
message
}
});
});
// Start the server
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Output
Now lets make a CustomError Handler in ExpressCustomError.js file workflow
- CustomError inherits from the built-in Error class to create structured custom errors.
- The statusCode property is added to represent different types of errors (e.g., 400 for bad requests).
- Passes the error message to the parent Error class, ensuring proper error message handling.
- Removes the constructor from the stack trace, making debugging cleaner.
- Allows this custom error class to be used in other files, such as an Express server for handling errors efficiently.
Server.js file workflow
- Creates an Express app instance and sets the server to run on port 3000.
- Uses express.json() to allow the server to handle incoming JSON data in requests.
- A GET request to this route throws a CustomError(400, "This is a custom error!") and forwards it to the next middleware.
- Catches all errors, retrieves the statusCode and message, and sends a structured JSON response with the error details.
- Calls app.listen(3000) to start the server, logging "Server is running on port 3000".
Advantages of using Custom Error Handler
- Centralized Error Handling: Avoids repetitive error-handling logic in multiple routes by managing all errors in one place.
- Consistent Error Responses: Ensures all errors follow a structured format, making it easier for clients to understand and debug issues.
- Better Debugging with Clean Stack Traces: Using Error.captureStackTrace() removes unnecessary function calls, making debugging more efficient.
- Custom Status Codes & Messages: Allows setting specific HTTP status codes and messages for different types of errors (e.g., 400 for bad requests, 404 for not found).
- Improved Maintainability: Keeps the codebase clean and organized, making it easier to modify or extend error-handling logic in the future.
Conclusion
Using a custom error handler in Express ensures a centralized, consistent, and structured approach to handling errors. It improves debugging, maintainability, and user experience by providing clear error messages and appropriate HTTP status codes. By implementing a global error-handling middleware, developers can reduce redundant code and maintain a clean, efficient server structure.
Similar Reads
Non-linear Components In electrical circuits, Non-linear Components are electronic devices that need an external power source to operate actively. Non-Linear Components are those that are changed with respect to the voltage and current. Elements that do not follow ohm's law are called Non-linear Components. Non-linear Co
11 min read
JavaScript Tutorial JavaScript is a programming language used to create dynamic content for websites. It is a lightweight, cross-platform, and single-threaded programming language. It's an interpreted language that executes code line by line, providing more flexibility.JavaScript on Client Side: On the client side, Jav
11 min read
Web Development Web development is the process of creating, building, and maintaining websites and web applications. It involves everything from web design to programming and database management. Web development is generally divided into three core areas: Frontend Development, Backend Development, and Full Stack De
5 min read
Spring Boot Tutorial Spring Boot is a Java framework that makes it easier to create and run Java applications. It simplifies the configuration and setup process, allowing developers to focus more on writing code for their applications. This Spring Boot Tutorial is a comprehensive guide that covers both basic and advance
10 min read
React Interview Questions and Answers React is an efficient, flexible, and open-source JavaScript library that allows developers to create simple, fast, and scalable web applications. Jordan Walke, a software engineer who was working for Facebook, created React. Developers with a JavaScript background can easily develop web applications
15+ min read
React Tutorial React is a powerful JavaScript library for building fast, scalable front-end applications. Created by Facebook, it's known for its component-based structure, single-page applications (SPAs), and virtual DOM,enabling efficient UI updates and a seamless user experience.Note: The latest stable version
7 min read
JavaScript Interview Questions and Answers JavaScript is the most used programming language for developing websites, web servers, mobile applications, and many other platforms. In Both Front-end and Back-end Interviews, JavaScript was asked, and its difficulty depends upon the on your profile and company. Here, we compiled 70+ JS Interview q
15+ min read
Class Diagram | Unified Modeling Language (UML) A UML class diagram is a visual tool that represents the structure of a system by showing its classes, attributes, methods, and the relationships between them. It helps everyone involved in a projectâlike developers and designersâunderstand how the system is organized and how its components interact
12 min read
Backpropagation in Neural Network Back Propagation is also known as "Backward Propagation of Errors" is a method used to train neural network . Its goal is to reduce the difference between the modelâs predicted output and the actual output by adjusting the weights and biases in the network.It works iteratively to adjust weights and
9 min read
3-Phase Inverter An inverter is a fundamental electrical device designed primarily for the conversion of direct current into alternating current . This versatile device , also known as a variable frequency drive , plays a vital role in a wide range of applications , including variable frequency drives and high power
13 min read