Перехват всех ошибок в обработчиках экспресс-маршрутов async-await - PullRequest
0 голосов
/ 26 апреля 2018

Предположим, у меня есть такой маршрут:

app.get('/broken', (req, res) => {
  throw new Error('Broken!');
});

Это никогда не отправит ответ клиентам.

Однако я могу добавить промежуточное ПО для всех ошибок:

const errorMiddleware = (error, req, res, next) => {
  if (error) {
    console.error(error);
    return res.status(500)
      .json({
        message: 'Internal server error', 
      });
  }
  next(error);
};

Но это не будет работать для async маршрутов, потому что они не throw напрямую.

Например, это не будет работать:

app.get('/broken', async (req, res) => {
  throw new Error('Broken!');
});

Так что я могу создать обертку так:

const asyncRoute = f => (req, res, next) => {
  return Promise.resolve(f(req, res, next)).catch(next);
};

app.get('/broken', asyncRoute(async (req, res) => {
  throw new Error('Broken!');
}));

Но это настоящая боль, потому что теперь я должен вызывать эту функцию для каждого маршрута!

Как лучше справиться с этим?


1 Ответ

0 голосов
/ 26 апреля 2018

По сути, вы не хотите напрямую передавать async функцию в app.get Express, потому что app.get не обрабатывает обещание, которое возвращает функция. Поэтому вам нужно обернуть эти async обработчики (как вы делаете).

Вы можете избежать необходимости делать это каждый раз, предоставив себе служебный метод в верхней части модуля:

const appGet = handler => app.get(asyncRoute(handler));

затем используйте его вместо app.get:

appGet('/broken', async (req, res) => {
  throw new Error('Broken!');
});

В какой-то момент (возможно, не сейчас) вы можете захотеть взглянуть на Коа .

...