Hoa
Hoa

Reputation: 20438

How can I get Express.js to 404 only on missing routes?

At the moment I have the following which sits below all my other routes:

app.get('*', function(req, res){
  console.log('404ing');
  res.render('404');
});

And according to the logs, it is being fired even when the route is being matched above. How can I get it to only fire when nothing is matched?

Upvotes: 65

Views: 118762

Answers (8)

Charles
Charles

Reputation: 11778

You just need to put it at the end of all route.

Take a look at the second example of Passing Route Control:

var express = require('express')
  , app = express.createServer();

var users = [{ name: 'tj' }];

app.all('/user/:id/:op?', function(req, res, next){
  req.user = users[req.params.id];
  if (req.user) {
    next();
  } else {
    next(new Error('cannot find user ' + req.params.id));
  }
});

app.get('/user/:id', function(req, res){
  res.send('viewing ' + req.user.name);
});

app.get('/user/:id/edit', function(req, res){
  res.send('editing ' + req.user.name);
});

app.put('/user/:id', function(req, res){
  res.send('updating ' + req.user.name);
});

app.get('*', function(req, res){
  res.status(404).send('what???');
});

Blockquote

app.listen(3000); 

Alternatively you can do nothing because all route which does not match will produce a 404. Then you can use this code to display the right template:

app.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.render('404.jade');
    } else {
        next(err);
    }
});

It's documented in Error Handling.

Upvotes: 95

Muhammad Abdullah
Muhammad Abdullah

Reputation: 4515

We need to handle the Error and Not-Found collectively as

Write two separate middleware for each,

// Import necessary modules
const express = require('express');

// Create a new Express app
const app = express();

// Define routes and middleware functions
app.get('/', (req, res) => {
    res.send('Hello World!');
});

// Catch 404 Not Found errors and forward to error handler
app.use((req, res, next) => {
    const error = new Error('Not Found');
    error.status = 404;
    next(error);
});

// Error handler middleware function
app.use((err, req, res, next) => {
    // Set status code and error message based on error object
    res.status(err.status || 500);
    res.send({
        error: {
            message: err.message
        }
    });
});

// Start the server
app.listen(3000, () => {
    console.log('Server started on port 3000');
});

Upvotes: 0

MD SHAYON
MD SHAYON

Reputation: 8053

Very simple you can add this middleware.

app.use(function (req, res, next) {
//Capture All 404 errors
  res.status(404).render("404.ejs")
})

404 error in a service is typically used to denote that the requested resource is not available. In this article we will see how to handle 404 error in express.

Upvotes: 1

The Creators
The Creators

Reputation: 45

You can use this

const express = require('express');
const app=express();
app.set('view engine', 'pug');
app.get('/', (req,res,next)=>{
    res.render('home');
});
app.use( (req,res,next)=>{
    res.render('404');
})
app.listen(3000);

Upvotes: 3

Nikhil Singh
Nikhil Singh

Reputation: 1610

You can this at the end of all routes,

const express = require('express');
const app = express();
const port = 8080;

// All your routes and middleware here.....

app.use((req, res, next) => {
    res.status(404).json({
        message: 'Ohh you are lost, read the API documentation to find your way back home :)'
    })
})

// Init the server here,
app.listen( port, () => {
    console.log('Sever is up')
})

Upvotes: 8

Thai Ha
Thai Ha

Reputation: 1379

Hope it helpful, I used this code in bottom of routes

router.use((req, res, next) => {
    next({
        status: 404,
        message: 'Not Found',
    });
});

router.use((err, req, res, next) => {
    if (err.status === 404) {
        return res.status(400).render('404');
    }

    if (err.status === 500) {
        return res.status(500).render('500');
    }

   next();
});

Upvotes: 6

kiko carisse
kiko carisse

Reputation: 1784

I wanted a catch all that would render my 404 page only on missing routes and found it here in the error handling docs https://expressjs.com/en/guide/error-handling.html

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(404).render('404.ejs')
})

This worked for me.

Upvotes: 1

Justin Elkow
Justin Elkow

Reputation: 2943

I bet your browser is following up with a request for the favicon. That is why you are seeing the 404 in your logs after the 200 success for the requested page.

Setup a favicon route.

Upvotes: 14

Related Questions