Страница 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 не используется.