DEV Community

Bentil Shadrack
Bentil Shadrack

Posted on • Updated on

How to write Custom Error Handler Middleware in Express.js using JavaScript 👩‍💻

What is Error Handler

Error handler is responsible of identifying and handling runtime issues.
Express.js comes pre-configured with a built-in Error Handler by default.

Error Handlers In ExpressJS🚀

Whenever a server error occurs, Express.js detects it and, unless you have a custom error handler, uses its built-in error handler to send a response to the client with the error message. Not only is Express.JS keen to handler errors properly but also to correctly empty away any unused resources when the application starts up again.

How to write Custom Error Handler Middleware in Express.js using JavaScript🚀

1. Create Custom ErrorHandler middleware

Folder Structure

// ErrorHandler.js
const ErrorHandler = (err, req, res, next) => {
    console.log("Middleware Error Hadnling");
    const errStatus = err.statusCode || 500;
    const errMsg = err.message || 'Something went wrong';
        success: false,
        status: errStatus,
        message: errMsg,
        stack: process.env.NODE_ENV === 'development' ? err.stack : {}

export default ErrorHandler
Enter fullscreen mode Exit fullscreen mode

NOTE: _ err.stack shows the exact file and line number the error occured. This is only needed in developement mode to debug your code. It becomes dangerous when your project structure is exposed on production_

2. Attach Custom Error Handler as The Last Middleware to Use

// index.js (Server Entery File)
import { AuthRoute, CategoryRoute, HomeRoute, PostRoute, UserRoute } from "./routes/index.routes.js";

import ErrorHandler from "./middlewares/ErrorHandler.js";

// init app
const app = express();

app.use("/", HomeRoute);
app.use("/user", verifyAccessToken, UserRoute);
app.use("/categories", CategoryRoute);
app.use("/posts", PostRoute)
app.use("/auth", AuthRoute);

// ERROR HANDLER MIDDLEWARE (Last middleware to use)

Enter fullscreen mode Exit fullscreen mode

3. How to Call the ErrorHandler

to call the ErrorHandler, Use the next() in Express.
The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.

app.use("/books", (req, res, next) => {
      // code block to be executed
Enter fullscreen mode Exit fullscreen mode

Sample Error Response on Production

production error

Sample Error Response in developement✔

Developemnt error

Why Should I Create Custom ErrorHandler instead of using the built-in ErrorHandler👀

You might want to create a custom errorhandler for a number of reasons.
For instance, some projects don't set NODE_ENV to "production" during the production stages. If error is not handled correctly, this could result in the disclosure of sensitive information about the server.
Other projects needs different error object format be sent at different points.

As a developer, It is very important to handler all error correctly to avoid crushing your APP anytime an error occurs.

Bentil here🚀
If you like my content, you can support me here to keep up the work.👇

buy me a coffee

Let me know your questions or suggestions in the comment box below

Top comments (16)

bbonsaye profile image

Hey, thank you for this article. Do you mind sharing how your routes file is structured? The way mine is structured is that all the routes are on the router object and I export that route object and within app.js I have

Enter fullscreen mode Exit fullscreen mode

I like how yours is explicit, I'm not sure how I can import each route by name the way you have it setup.
Thanks in advance.

qbentil profile image
Bentil Shadrack

Project Structure


Routes Structure:


This is how each route looks like


For easy export and import, I have created the index.route.js to export all routes from a single file


So I can easily import the routes like this

Instead of importing them from their separate files.

This is a typical backend repo of mine. You can check it out

bbonsaye profile image
bbonsaye • Edited

Thank you for sharing that, I'm going to separate my routes like that too. If I may, I seen a video of someone who had a ".env" file in the root directory and a config folder located in "/src/config" and within that config.js file, they basically copied the variables in ".env" and pasted them in "config.js" and exported them to be used in their code.

Right now, I only have the ".env" file and access the variables located within it using the "process.env" object within my code, example: "process.env.HOST"

I like the idea of accessing the environment variables like so; "config.HOSTNAME" but, I find it redundant and time consuming to always update "/configs/config.js" every time we add a new variable to ".env"

Is that what you are doing or have you found a way where every time you add/remove a new variable in ".env" it automatically adds/removes the variable in "/configs/config.js"?

by the way, I just checked out your GitHub Portfolio briefly and noticed a minor typo. In your "ABOUT ME" you have "(Coud Storage)" I think you meant, "(Cloud Storage" -- tryna help hope that's not annoying to point out.

Thread Thread
qbentil profile image
Bentil Shadrack

I also use the same approach you are using now.
I access the env variables through the process.env.NAME

Thank you very much for the feedback on my readme. I really Appreciate.🥰🎉
I will check it out asap

miguelznunez profile image
Miguel Z. Nunez

Can you show me how I would go about implementing this error handler with try catch in the following GET route? The route makes a query to a database table named images and sends the data over to the frontend. If there is some kind of error in accessing the data, I'm not sure how to go about grabbing the database error. I am using "throw new Error" but that only stops the program on its tracks. I want to be able to get the error in JSON and send the error to the user if possible.

app.get("/", (req, res) => {
dbConnection.query("SELECT * FROM images WHERE user_id = ?", [1], (err, result) => {
if(!err) res.render("index", {images:result})
else throw new Error(err)

qbentil profile image
Bentil Shadrack

Hello Miguel, You can put it this way if you have your errorhandler middleware in place

app.get("/", (req, res, next) => {
    try {
        dbConnection.query("SELECT * FROM images WHERE user_id = ?", [1], (err, result) => {
            res.render("index", { images: result })
    } catch (error) {
Enter fullscreen mode Exit fullscreen mode

I hope this help☺

javadsh profile image

Even if we don't use a try and catch and even if we don't use next(), the errors in the route are accessible in error handler middleware.
What is the reason for using the try and catch?
I would also be grateful if you could tell me how to customize the errors of each root in itself.I mean how to set for example error message and or name in every route.

qbentil profile image
Bentil Shadrack

Without the next() The errors will not be handled by your error Handler middleware. It will be handled by Express framework’s default error handler

Errors that are created by asynchronous functions that are called from route handlers, need to be handled differently. The error from asynchronous functions are not handled by the default error handler in Express which can result in crashing the entire App. Putting then in a try catch block will help you handle those errors separately using you custom error handler

yogeshyadav profile image
Yogesh Yadav

This was simple and straightforward. Thanks for sharing.

qbentil profile image
Bentil Shadrack

I am glad you like it✨🚀

ethel3 profile image
Ethel Akrasi Akosua

This piece was very helpful.

qbentil profile image
Bentil Shadrack

Thank youu

krishnacyber profile image

Hey, very very thank you for this article. This helps me a lot and finding you a good guy.. keep sharing and shining 🌟🌟

qbentil profile image
Bentil Shadrack

Hey Krishna
Thank you for the positive feedback.
I'm glad you found this helpful🙌

nanaole profile image
Offei Emmanuel

I will try it. N thanks to the creator of d content. You putting out priceless information for free..... 💯. Continue the good work.

qbentil profile image
Bentil Shadrack

You are most welcome
I'm glad you like it