Express (Node) - правильный способ отправки сообщений об ошибках через цикл промежуточного программного обеспечения - PullRequest
0 голосов
/ 24 сентября 2018

В правильных приложениях, как правильно отправлять сообщения об ошибках в представления?

(мы предполагаем, что код является синхронным)

Пример 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)), но я надеялся на лучший путь.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Я не уверен, что понял всю вашу проблему, но я бы использовал промежуточное ПО для обработки ошибок, например:

// firstMiddleware
var firstMiddleware = function (req, res, next) {
  doAlsoSomething(function (err, datas) {
    if (err) { next('error message'); }
    // ...
    next(); // If err is true calls renderView
  });
};

// otherMiddleware
var otherMiddleware = function (req, res, next) {
  // Do stuff only if no error
  next();
};

// Controller
Controller.getIndex = function (req, res, next) {
  doSomething(function (err, datas) {
    if (err) { next('error message'); }
    // ...
    next(); // If err is true calls renderView
  });
};

// This middleware runs after next('error message')
var handleError = function (err, req, res, next) {
  res.locals.err = err.message;
}

// This middleware always runs
var renderView = function (req, res, next) {
  res.render(/* view */);
}

// Route
Router.route('/')
  .get(firstMiddleware, otherMiddleware/*, otherMiddleware2, etc */, controller.getIndex, handleError, renderView);
0 голосов
/ 24 сентября 2018

Если вы используете otherMiddleware только один раз, избавьтесь от него, а затем переместите его содержимое в блок else предыдущего промежуточного ПО:

var checkForm = function (req, res, next) {
  validationResult(function (err, datas) {
    if (err) { res.locals.err = 'error message'; }
    else {
      // Do stuff only if form is valid
      // otherMiddleware code
    }
    // ...
  });
  next();
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...