Вау .. Моя первая история. Ну, давайте попробуем)
Каждый из нас думал, как сделать хорошую обработку ошибок с логированием, масштабируемостью и сделать эту систему гибкой. Я собираюсь поделиться с вами своими мыслями о том, как это сделать, и хотел бы поговорить о том, какую структуру вы можете использовать в своих приложениях 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 вы можете найти ниже. До свидания!