2016-07-31 5 views
1

Я создал следующий Экспресс стек 4 промежуточного слоя:Express 4 промежуточное программное обеспечение, когда маршрут не найден (окончательный обработчик не вызывается): как его проверить?

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

Если я позвоню сервер с маршрутом, который не существует (например, GET/кое-что) функция SendResponse только после того, как обработчик маршрутизатора называется и вызывающий получает стандартный ответ вместо обычного сообщения «Can not GET/something», исходящего из модуля finalhandler.
Я думал, что обработчик ошибок должен был быть вызван, но это не тот случай.
Есть ли способ заставить маршрутизатор испускать ошибку, если маршрут не найден или проверить стандартный ответный обработчик, если маршрут не был согласован?
Я знаю, что я могу добавить значение в res.locals для любого маршрута, который имеет соответствие, и проверить его в стандартном обработчике ответов, но я бы хотел использовать «правильный» способ сделать это, а не использовать обходной путь.

+0

Является ли изменение 'app.use (SendResponse)' в 'app.use (функция (Req, Рез, следующий) {следующий (новый Error (404));});' решить вашу проблему? , –

+0

Совсем нет, потому что в этом случае ошибка 404 возникает, даже когда маршрут найден –

+0

Вы вызываете 'next()' в функции маршрутизатора для вызова 'sendResponse', правильно? –

ответ

4

Вы можете проверить 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!'); 
}); 
+1

Да! Проверка req.route - это то, что я искал, спасибо –

0

Обработчик ошибок на случай, если произошла ошибка. Никакой соответствующий маршрут не является ошибкой. Я предполагаю, что посредники, вызываемые вашим маршрутизатором, не возвращают ответ клиенту, и поэтому вам потребуется промежуточное ПО sendResponse. Вы можете изменить это и вернуть ответ клиенту в посредниках маршрутизатора и после использования маршрутизатором промежуточного программного обеспечения, которое возвращает ошибку, не найденную маршрутом. Если вы дошли до этого промежуточного слоя, это означает, что маршрут не был согласован.

+0

Правда, но на самом деле у меня более ста маршрутов, и я не хотите поместить один и тот же вызов sendResponse во всех них. Кажется настолько аккуратным и чистым, что у меня есть только один запрос sendResponse (получение данных из res.locals.data) в качестве промежуточного программного обеспечения. –

1

Я использую следующую логику:

... 

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

Надеется, что это помогает ..

+0

. По-моему, вы отправляете ответ в файлах маршрутов, пока я отправляю ответ с помощью последней функции промежуточного программного обеспечения , В вашем случае вам даже не нужно добавлять маршрут «*», потому что экспресс уже хорошо обрабатывает этот случай через модуль finalhandler. –

+0

Да, вы правы. Я могу удалить часть «*». Я бы прописал этот код около двух лет назад :) – efkan