问题
I set up the following Express 4 middleware stack:
const app = express();
const router = express.Router();
router.get('/test', testResponse);
app.use(checkAccessToken);
app.use(router);
app.use(sendResponse);
//Error Handling
app.use(function(err,req,res,next) {
// ... Do something here
});
function sendResponse(req, res) {
res.json({
data: res.locals.data,
meta: res.locals.meta
});
}
If I call the server with a route that doesn't exist (like GET /something) the function sendResponse just after the router handler is called and the caller gets a standard response instead of the usual message "Cannot GET /something", coming from the finalhandler module.
I thought instead that the error handler should have been called, but this is not the case.
Is there a way to force the router to emit an error if a route is not found or to check in the standard response handler if a route has not been matched?
I know that I can add a value in res.locals for any route that has a match and check for it in the standard response handler, but I'd like to use the "right" way to do it, rather than using a workaround.
回答1:
You can check req.route.
var express = require('express');
var app = express();
app.use(require('body-parser').urlencoded({extended: false}));
const router = express.Router();
router.use(function(req, res, next) {
app.locals.test = 0;
next();
});
router.get('/', function(req, res, next) {
app.locals.test = 10;
next();
});
router.get('/about', function(req, res, next) {
app.locals.test = 20;
next();
});
router.use(function(req, res, next) {
if (!req.route)
return next (new Error('404'));
next();
});
router.use(function(err, req, res, next){
res.send(err.message);
})
router.use(function(req, res){
res.send(app.locals.test + '');
});
app.use(router);
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
回答2:
I use the following logic:
...
app.use(require('./routes/eInvoice'))
app.use(require('./routes/oauth2/client'))
// Status 404 (Error) middleware
app.use('*', function(req,res){
res.status(404)
if(req.headers.accept.indexOf('html'))
res.render('404', { url: req.protocol + '://' + req.get('host') + req.originalUrl })
else
res.send("URL cannot found")
})
// Error handling
app.use(require("./middlewares/errorHandler"))
app.listen(config.operating.port, function() {
console.log('Operating Server is listening HTTP port ' + config.operating.port)
})
Hope this helps..
回答3:
The error handler is in case there was an uncaught error. No matching route is not an error. I assume the middlewares called by your router don't return the response to the client and therefore you need the sendResponse middleware. You can change that and return the response to the client in the router middlewares and after the router use a middleware that return the route not found error. If you got to this middleware it means no route was matched.
来源:https://stackoverflow.com/questions/38681318/express-4-middleware-when-route-is-not-found-finalhandler-not-called-how-to-c