Как настроить обработку ошибок в express.js?

Как можно обрабатывать критические ошибки в серверном приложении на node.js + express.js таким образом, чтобы приложение не останавливалось из-за одной ошибки, а только прекращало обработку конкретного запроса, который вызвал ошибку? В PHP для каждого запроса создается отдельный процесс, и если что-то идет не так, отпадает только один клиент. Однако в Node.js все клиенты падают сразу. Какие есть способы решения данной проблемы?
  • 12 февраля 2024 г. 10:38
Ответы на вопрос 2
Для настройки обработки ошибок в приложении Express.js следует использовать Middleware функции обработки ошибок. Они определяются так же, как и обычные middleware, за исключением того, что функции обработки ошибок принимают четыре аргумента вместо трех (`err, req, res, next`).

Вот пример пользовательского обработчика ошибок:

```javascript
app.use(function(err, req, res, next) {
  console.error(err.stack); // Логируем стек ошибки
  res.status(500).send('Что-то пошло не так!');
});
```

Для того чтобы предотвратить "падение" всего приложения из-за одной ошибки, необходимо уметь правильно её обработать. В Node.js есть несколько способов предотвратить завершение работы приложения из-за непредвиденных ошибок:

1. **Правильное использование промисов и async/await**: Если используете промисы или async/await, убедитесь, что вы всегда обрабатываете ошибки с помощью блоков `.catch()` или `try...catch`.

```javascript
app.get('/route', async (req, res, next) => {
  try {
    // Ваш асинхронный код
  } catch (err) {
    next(err); // Передача ошибки следующему обработчику
  }
});
```

2. **Обработчик uncaughtException**: Это событие возникает, когда выброшена ошибка, которая не была перехвачена. Вы можете добавить слушателя для этого события на уровне процесса, чтобы предотвратить завершение работы приложения:

```javascript
process.on('uncaughtException', (err) => {
  console.error('Неперехваченное исключение:', err);
  // Делаем необходимые действия перед выходом, например логирование и чистку
  process.exit(1); // В реальном приложении может быть gracefull shutdown
});
```

3. **Обработчик unhandledRejection**: Это событие возникает из-за промисов, которые были отклонены и для которых не были предусмотрены обработчики `.catch`. Оно может служить дополнительной сетью безопасности для перехвата таких ошибок.

```javascript
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  // Можно также предусмотреть логику восстановления или остановки приложения
});
```

4. **Использование процесс менеджеров, таких как PM2**: PM2 может автоматически перезапускать ваше приложение в случае сбоя, поддерживая его работоспособность.

```shell
pm2 start app.js
```

5. **Модуль 'Domain'**: 

**Примечание**: Стоит учитывать, что использование модуля 'Domain' может не гарантировать полную изоляцию ошибок и его использование на текущий момент (начало 2023 года) считается устаревшим (deprecated). Вместо него рекомендуется использовать альтернативные подходы, например, использование промисов с блоками try/catch или асинхронные функции с обработчиками ошибок.

Независимо от выбранного способа, критически важно всегда предусматривать обработку возможных ошибок на каждом этапе выполнения вашего приложения, чтобы минимизировать риск непредвиденного его завершения.
Оберните содержимое каллбэков в try catch: 
try catch

Тогда ваше приложение не будет падать при ошибках в логике.

Если по нормальному, помимо промисов и try catch, обрабатывать их до логики: https://expressjs.com/en/guide/error-handling.html... .

Здесь вы можете разгуляться по полной.
Похожие вопросы