Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Страница 404 и обработка ошибок

Когда ни один маршрут не подошёл, Express отвечает скупым текстом «Cannot GET /адрес». А если в обработчике случилась ошибка, посетитель увидит технический текст с кодом. Обе ситуации перехватывают своими middleware в самом конце src/app.js.

Страница 404

Middleware, подключённая после всех маршрутов, получит только те запросы, которые никто не обработал:

// src/app.js
app.use('/posts', postsRouter);
 
app.use((req, res) => {
  res.status(404).send('<h1>Страница не найдена</h1><a href="/posts">К статьям</a>');
});

Откройте http://localhost:3000/nothing — появится заголовок «Страница не найдена» и ссылка на список статей. Когда в курсе появятся шаблоны, здесь будет res.status(404).render('404').

Обработчик ошибок

Обработчик ошибок отличается от обычной middleware тем, что принимает четыре аргумента. Первым приходит сама ошибка:

// src/app.js
app.use((error, req, res, next) => {
  console.error(error);
  res.status(500).send('<h1>Что-то пошло не так</h1>');
});

Его ставят последним, после страницы 404. Подробности ошибки пишутся в терминал для разработчика, а посетитель видит спокойное сообщение.

Как ошибка туда попадает

Если в обработчике маршрута выброшено исключение, Express сам поймает его и передаст в обработчик ошибок:

// src/controllers/postsController.js
export function show(req, res) {
  const post = posts.find((item) => item.id === Number(req.params.id));
 
  if (!post) {
    const error = new Error('Статья не найдена');
    error.status = 404;
    throw error;
  }
 
  res.send(post.title);
}

Передать ошибку можно и явно — вызовом next(error). Всё, что вызвано с аргументом, Express считает ошибкой и пропускает обычные middleware.

Код ответа из ошибки

Чтобы один обработчик умел отвечать и 404, и 500, берите код из ошибки:

// src/app.js
app.use((error, req, res, next) => {
  const status = error.status ?? 500;
 
  if (status === 500) {
    console.error(error);
  }
 
  res.status(status).send(status === 404 ? 'Не найдено' : 'Ошибка сервера');
});

Теперь /posts/99 вернёт «Не найдено» с кодом 404, а настоящая поломка — «Ошибка сервера» с кодом 500 и записью в терминале.

Порядок в app.js

МестоЧто подключается
НачалоОбщие middleware: разбор тела, статика
СерединаМаршруты
ПредпоследнимСтраница 404
ПоследнимОбработчик ошибок

Частая ошибка

Express узнаёт обработчик ошибок только по числу аргументов. Если написать (error, req, res) => ... без next, функция получит три аргумента и будет считаться обычной middleware — ошибки в неё не попадут. Указывайте все четыре параметра, даже если next не используется.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.