2016-07-31 34 views
1

ich den folgenden Express 4-Middleware-Stack:Express 4 Middleware wenn Route nicht gefunden wird (Endhandler nicht aufgerufen): Wie kann man danach suchen?

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 
    }); 
} 

Wenn ich rufe Sie den Server mit einer Route, die nicht (wie GET/etwas) Handler der Funktion sendresponse ist kurz nach dem Router existiert genannt und die Der Aufrufer erhält eine Standardantwort statt der üblichen Nachricht "Can not GET/something", die vom Finalhandler-Modul kommt.
Ich dachte stattdessen, dass der Fehlerhandler hätte aufgerufen werden sollen, aber das ist nicht der Fall.
Gibt es eine Möglichkeit, den Router dazu zu zwingen, einen Fehler auszulösen, wenn eine Route nicht gefunden wird, oder den standardmäßigen Antworthandler einzuchecken, wenn eine Route nicht gefunden wurde?
Ich weiß, dass ich einen Wert in res.locals für jede Route hinzufügen kann, die eine Übereinstimmung und überprüfen Sie im Standard-Antwort-Handler dafür, aber ich möchte den "richtigen" Weg, um es zu tun, anstatt zu verwenden ein Workaround.

+0

Ist Änderung 'app.use (sendresponse);' auf 'app.use (function (req, res, next) {nächste (neu Error (404));});' Ihr Problem lösen? . –

+0

Überhaupt nicht, denn in diesem Fall wird der Fehler 404 ausgelöst, selbst wenn die Route gefunden wird. –

+0

Rufen Sie 'next()' in der Routerfunktion an, um 'sendResponse' aufzurufen, oder? –

Antwort

4

Sie req.route überprüfen können.

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!'); 
}); 
+1

Ja! Ich habe nach req.route gesucht, danke –

0

Der Error-Handler ist für den Fall, dass ein nicht abgefangener Fehler aufgetreten ist. Keine passende Route ist kein Fehler. Ich nehme an, die Middlewares, die von Ihrem Router aufgerufen werden, geben die Antwort an den Client nicht zurück und daher benötigen Sie die sendResponse Middleware. Sie können dies ändern und die Antwort an den Client in den Router-Middlewares zurückgeben und nach dem Router eine Middleware verwenden, die den Fehler Route nicht gefunden zurückgibt. Wenn Sie zu dieser Middleware gelangen, bedeutet dies, dass keine Route gefunden wurde.

+0

True, aber in Wirklichkeit habe ich mehr als hundert Routen und ich nicht Ich möchte den gleichen Aufruf an sendResponse in allen senden. Es scheint so sauber und ordentlich zu sein, nur eine sendResponse (Daten aus res.locals.data) als Middleware zu haben –

1

Ich verwende die folgende Logik:

... 

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) 
}) 

this helps ..

+0

Sie senden die Antwort in den Routen-Dateien, denke ich, während ich die Antwort mit der letzten Middleware-Funktion sende . In Ihrem Fall müssen Sie noch nicht einmal eine '*' Route hinzufügen, weil Express diesen Fall bereits gut durch das Finalhandler-Modul behandelt. –

+0

Ja, du hast Recht. Ich kann '*' Teil entfernen. Ich habe diesen Code vor zwei Jahren geschrieben :) – efkan