Вау .. Моя первая история. Ну, давайте попробуем)

Каждый из нас думал, как сделать хорошую обработку ошибок с логированием, масштабируемостью и сделать эту систему гибкой. Я собираюсь поделиться с вами своими мыслями о том, как это сделать, и хотел бы поговорить о том, какую структуру вы можете использовать в своих приложениях nodejs.

Итак, поехали.

Прежде всего, давайте сделаем довольно простой сервер nodejs / express с парой маршрутов.

Хороший. Теперь добавим пару контроллеров. Один из них просто выдаст некоторые данные ответа, но другой вызовет ошибку.

Если мы запустим сервер и перейдем к `localhost: 3000 / two`, он потерпит неудачу вот так

Его можно легко перехватить, добавив одно промежуточное ПО

app.use((err, req, res, next) => {
  res.json({ message: err.message });
});

Теперь мы обрабатываем ошибки по всем маршрутам, но упустили одну вещь: у каждой ошибки может быть свой код статуса.

Давайте добавим новый маршрут с параметром :id в пути

app.get("/:id", (req, res) => {
  const data = userCtrl(req.params.id);
  res.json({ message: data.name });
});

userCtrl рассмотрим чуть позже.

Теперь мы подошли к одному из способов решения нашей основной проблемы. Создайте файл exceptions.js и поместите туда это содержимое

Общая идея - реализовать собственный класс ошибок на основе Error и расширить его всеми необходимыми полями. Вы также можете добавить туда пользовательское ведение журнала.

Добавьте новый контроллер и имитируйте БД (просто создайте простой объект, который будет отображать идентификаторы с именами). Теперь controllers.js выглядит так

Пришло время поиграть со всем этим. Перейти на новый маршрут с идентификатором 1

И также проверьте этот маршрут на id 12

Большой. Теперь мы можем увидеть сообщение об ошибке, которое и ожидаем. Но статус по-прежнему 200. Нам нужно немного обновить промежуточное ПО для ошибок:

app.use((err, req, res, next) => {
  const { statusCode = 500 } = err;
  res.status(statusCode).json({ message: err.message });
});

Здесь мы проверяем код состояния из переменной err и, если он отсутствует - устанавливаем код состояния по умолчанию 500.

В нашем случае мы получим ошибку 404. Прохладный!

Такой рост ошибки мы можем реализовать другим способом: вместо передачи объекта Error в качестве параметра throw вы можете передать туда простой объект, подобный этому

throw { message: "Value param is broken", statusCode: 404 };

Обработка этой ошибки будет такой же, как и в предыдущем случае.

Первый способ имеет два преимущества:
1) полностью настраиваемый
2) вы можете отследить ошибку с помощью обработки поля err.stack и получить поврежденное место вашего кода.

Второй способ довольно прост и не требует много кода.

Спасибо за чтение. Ссылку на github вы можете найти ниже. До свидания!