Search code examples
javascriptnode.jsexpressexpress-router

How to catch page not found in express router


I would like to catch 404 page not found error in express router.

I use a basic example :

const express = require('express');

const app = express();

const router = express.Router();

// ROUTER MID BEFORE
router.use((req, res, next) => {console.log("Router Mid => Before"); next();});

// ROUTER PAGE /BAR
router.get('/bar', (req, res, next) => {
 console.log("Router page '/bar'");
 res.send('<body><h1>Hello World</h1></body>');
 next();
 }); 

// ROUTER NOT FOUND
router.get('*', (req, res, next) => {console.log("Router NOT FOUND"); next();});

// ROUTER MID AFTER
router.use((req, res, next) => {console.log("Router Mid => After"); next();});

// APP MID BEFORE
app.use((req, res, next) => {console.log("----"); console.log("App Mid => Before"); next();});

app.use('/foo', router);

// APP NOT FOUND
app.get('*', (req, res, next) => {console.log("App NOT FOUND"); next();});

// APP MID AFTER
app.use((req, res, next) => {console.log("App Mid => After"); console.log("----"); next();});

app.listen(3000, () => {console.log("App Listenning")});

I expect the following result :

Request on /anything

----
App Mid => Before
App NOT FOUND
App Mid => After
----

Request on /foo/anything

----
App Mid => Before
Router Mid => Before
Router NOT FOUND
Router Mid => After
App Mid => After
----

Request on /foo/bar

----
App Mid => Before
Router Mid => Before
Router page '/bar'
Router Mid => After
App Mid => After
----

But the Not Found page are executed on every requests

For example a Request /foo/bar gives me :

----
App Mid => Before
Router Mid => Before
Router page '/bar'
Router NOT FOUND
Router Mid => After
App NOT FOUND
App Mid => After
----

How can I achieve that ?


Solution

  • The only way I found to acheive that is to pass a custom flag along all the middleware. This way i can know if a route has already send a response or if i need to send a page not found.

    const express = require('express');
    const app = express();
    const router = express.Router();
    
    // Custom not found flag setup
    app.use((req, res, next) => {req.pageFound = false; next();});
    
    // ROUTER MID BEFORE
    router.use((req, res, next) => {console.log("Router Mid => Before"); next();});
    
    // ROUTER PAGE /BAR
    router.get('/bar', (req, res, next) => {
     req.pageFound = true;
     console.log("Router page '/bar'");
     res.send('<body><h1>Hello World</h1></body>');
     next();
    }); 
    
    // ROUTER NOT FOUND
    router.get('*', (req, res, next) => {
     if (req.pageFound === false) { 
      req.pageFound = true;
      console.log("Router NOT FOUND");
      next();
    }});
    
    // ROUTER MID AFTER
    router.use((req, res, next) => {console.log("Router Mid => After"); next();});
    
    // APP MID BEFORE
    app.use((req, res, next) => {console.log("----"); console.log("App Mid => Before"); next();});
    
    app.use('/foo', router);
    
    // APP NOT FOUND
    app.get('*', (req, res, next) => {
    if (req.pageFound === false) {
     req.pageFound = true;
     console.log("App NOT FOUND");
     next();
    }});
    
    // APP MID AFTER
    app.use((req, res, next) => {console.log("App Mid => After"); console.log("----"); next();});
    
    app.listen(3000, () => {console.log("App Listenning")});