Search code examples
javascriptnode.jsexpressmiddleware

Express: How can I forward errors with next


I wanted to create an error handler as middleware. My Idea was when I don't get any matching routes, I will generate a "route not found error" and use the next() parameter of express.

I'm somehow not able to redirect my generated error to my errorHandler.js. It is not called inside. Where is my mistake?

app.js:

....
// after no matching routes call this
app.use((req, res, next) => {
    const err = new Error("route not found");
    res.status(404);
    next(err);
});

// call the error handler
app.use(errorHandler);

errorHandler.js:

import { Router, Request, Response, NextFunction } from "express";

    
const errorHandler = Router();

errorHandler.use(
    (
        err,req,res,next
    ) => {
        res.status(err.status || 500);
        res.json({
            error: {
                message: err.message,
                error: {},
            },
        });
    }
);

When I use this in my errorHandler.js: the output is slightly different:

errorHandler.use((req, res, next) => {
    const err = new Error("route not found");
    res.status(404);
    next(err);
});

why is that so ?


Solution

  • errorHandler should be a middleware, NOT a router instance. You can add status property to err object and call next(err) forward the err to errorHandler middleware. Set the response status in error handler middleware centrally.

    app.js:

    import express from 'express';
    import { errorHandler } from './errorHandler';
    const app = express();
    
    app.get('/', (req, res) => {
      res.sendStatus(200);
    });
    
    app.use((req, res, next) => {
      const err = new Error('route not found');
      err.status = 404;
      next(err);
    });
    
    app.use(errorHandler);
    
    app.listen(3000, () => console.log('Server started at http://localhost:3000'));
    

    errorHandler.js:

    function errorHandler(err, req, res, next) {
      res.status(err.status || 500);
      res.json({
        error: {
          message: err.message,
          error: {},
        },
      });
    }
    
    export { errorHandler };
    

    Server logs:

    ⚡  curl http://localhost:3000       
    OK%     
    ⚡  curl -i http://localhost:3000/api/v1
    HTTP/1.1 404 Not Found
    X-Powered-By: Express
    Content-Type: application/json; charset=utf-8
    Content-Length: 50
    ETag: W/"32-X7VodneZlwbfTuc/IPekfp/Xol0"
    Date: Thu, 14 Jan 2021 10:01:07 GMT
    Connection: keep-alive
    
    {"error":{"message":"route not found","error":{}}}%