Adding the below middleware (and possibly rendering a self-defined error page) makes Express give the 404 error when all the routes provided before it does not match the current URL. If this middleware is added before a valid route, that route will be blocked and 404 error will be returned.

1
2
3
4
5
6
//404 Not Found Middleware
app.use(function (req, res, next) {
res.status(404)
.type('text')
.send('Route Not Found');
});

Async Issue

I met with an async issue when adding this middleware when doing the issue tracker fCC project.

1
2
3
4
5
6
7
8
9
//Routing for API
apiRoutes(app);

//404 Not Found Middleware
app.use(function(req, res, next) {
res.status(404)
.type('text')
.send('Not Found');
});

It looks like the api routes are added before 404 middleware, but the apiRoutes function needs to build a database connection before adding the routes:

1
2
3
4
5
6
7
/**apiRoutes*/
module.exports = function (app) {
MongoClient.connect(CONNECTION_STRING, (err, client) => {
const db = client.db("issues");
app.post('/api/issues/:project', function (req, res) {
// ...
})})}

Because of this delay, the traffic is caught by the 404 middleware instead, and I always get a 404 error when making a request to /api/issues/:project.

To solve this problem, I put the apiRoutes(app) just before app.listen, and put the 404 middleware INSIDE the callback of the db connection. This means all the api routes will be finished before the 404 middleware is added.

chai-http routes

When running integration test (functional test) with chai.request(app), because the request is sent right after the app is initiated, the api routes are not properly loaded either:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
test('Every field filled in', function (done) {
chai.request(app)
.post("/api/issues/test")
.send({
issue_title: 'Title',
issue_text: 'text',
created_by: 'Functional Test - Every field filled in',
assigned_to: 'Chai and Mocha',
status_text: 'In QA'
})
.end(function (err, res) {
assert.equal(res.status, 200, "Status should be 200!");
// assert fails with 404, because the db connection is not successful yet and api routes are not loaded to the server.
})})

This is how the code provided by fCC solves the problem:

1
2
3
4
5
6
7
8
9
10
11
if(process.env.NODE_ENV==='test') {
console.log('Running Tests...');
setTimeout(function () {
try {
runner.run();
} catch(e) {
const error = e;
console.log('Tests are not valid:');****
console.log(error);
}
}, 3500);}

It waits for 3.5 seconds for the test to start, to ensure that the tests are run upon a fully loaded server.