В правильных приложениях, как правильно отправлять сообщения об ошибках в представления?
(мы предполагаем, что код является синхронным)
Пример 1:
// Route
Router.route('/')
.get(controller.getIndex);
// Controller
Controller.getIndex = function (req, res, next) {
doSomething(function (err, datas) {
if (err) { res.locals.err = 'error message'; }
// ...
});
res.render(/* view */);
};
// View
<p class="error">${ out.global.err }</p>
Здесь нет проблем: если есть ошибка, я сохраняю сообщение в ответе и отображаю его в виде.
Пример 2:
// Route (with multiple middlewares)
Router.route('/')
.get(firstMiddleware, otherMiddleware/*, otherMiddleware2, etc */, controller.getIndex);
// firstMiddleware (always need to be called)
firstMiddleware = function (req, res, next) {
doAlsoSomething(function (err, datas) {
if (err) { res.locals.err = 'error message'; }
// ...
});
next();
};
// otherMiddleware, otherMiddleware2 (need to be called only if no errors)
otherMiddleware = function (req, res, next) {
next();
};
// Controller (need to be called only if want to display the view)
Controller.getIndex = function (req, res, next) {
doSomething(function (err, datas) {
if (err) { res.locals.err = 'error message'; }
// ...
});
res.render(/* view */);
};
// View
<p class="error">${ out.global.err }</p>
В этом примере otherMiddleware будетбыть всегда вызванным.Это не то, что я хочу, это должно остановить цикл промежуточного программного обеспечения в случае ошибок.Затем, если ошибки должны отображаться в представлении, он должен называться Controller.getIndex()
с сообщениями об ошибках, как в примере 1. Если ошибки имеют свои собственные представления (как 404, 500 ...), он не должен вызывать Controller.getIndex()
, носоответствующий вид.В любом случае, если ошибка возникает в otherMiddlewareX, промежуточное программное обеспечение «после» (otherMiddlewareX + 1, otherMiddlewareX + 2 ... otherMiddlewareN) не должно вызываться.
Любой может помочь мне найти «правильное»способ сделать это?
РЕДАКТИРОВАТЬ: аналогичная проблема аналогичный вопрос переполнения стека
Возможные ответы (я могу привести примериз реализаций, если необходимо):
- Поместите условие
if (res.locals.err)
в каждое промежуточное ПО для перехода к следующему в случае ошибок, вызвав next();
.Это не очень удобно. - Вызовите промежуточное программное обеспечение для обработки ошибок с
next('error message');
, но трудно управлять каждым перенаправлением в одной функции (это решение, которое я использую) - Использование
next('route');
с дублированием маршрута каждый раз для управления ошибками (аналогично промежуточному программному обеспечению для обработки ошибок). - Использование
res.redirect();
и флеш-сообщений (сеанс, строка запроса, дб, cookie ...).Если я использую это решение, мне нужно сделать его без сохранения состояния.Я мог бы сделать это, например, с помощью строки запроса, но мне это тоже не очень удобно.Более того, он не дает прямого ответа на вопрос, а скорее на вопрос о том, как передавать сообщения между запросами в REST API .
Вероятно, есть способ сделать это легко сЭкспресс приложение, но я не могу приехать, чтобы выяснить, что это правильный путь.Не могли бы вы помочь мне?
Спасибо заранее.
РЕДАКТИРОВАТЬ: Подробнее о возможных ответах (третье решение).
С next('error message');
У меня есть ошибка-промежуточное программное обеспечение обработчика, где мне нужно отобразить хороший вид.Представление может быть 500, 404, 406 ... но также 200 с сообщением об ошибке.Во-первых, мне нужно дать код состояния этому промежуточному программному обеспечению, затем, если это 200, мне нужно вызвать представление, соответствующее ошибке.Проблема в том, что я не всегда знаю, какой вид звонить.У меня может быть POST на / auth, который должен быть перенаправлен на GET / login.Мне нужно «жестко закодировать» его, и я не могу написать один и тот же код для каждой ситуации, или мне нужно передавать представление / контроллер при каждом вызове next('error message');
.Даже перенаправление трудное, потому что иногда мне нужно вызывать контроллер, но иногда мне нужно пройти через другой цикл промежуточного программного обеспечения, вызывая маршрут, а не контроллер, и единственный найденный мной способ - это return app._router.handle(req, res, next);
, который выглядит скорее как «взлом»«Это официальное решение.Если я перенаправить с res.redirect ();я вернулся ко второму возможному ответу, где мне нужно передать некоторые флеш-сообщения.В заключение, это решение, которое я использую (next(err)
), но я надеялся на лучший путь.