Обработка ошибок
Если обработчик бросает ошибку, Fastify ловит её сам и отвечает клиенту JSON с кодом ошибки. Ваша задача — бросать ошибки с правильным кодом и при желании настроить, как они выглядят.
Ошибка с кодом
Код ответа Fastify берёт из свойства statusCode ошибки. Без него получится 500:
// src/routes/posts.js
app.get('/posts/:id', async (request) => {
const post = app.posts.find((item) => item.id === request.params.id);
if (!post) {
const error = new Error('Статья не найдена');
error.statusCode = 404;
throw error;
}
return post;
});/posts/99 вернёт {"statusCode":404,"error":"Not Found","message":"Статья не найдена"}.
@fastify/sensible
Создавать ошибку вручную долго. Официальный плагин @fastify/sensible добавляет готовые функции:
npm install @fastify/sensible// src/app.js
import sensible from '@fastify/sensible';
app.register(sensible);Теперь в любом маршруте доступны app.httpErrors:
// src/routes/posts.js
app.get('/posts/:id', async (request) => {
const post = app.posts.find((item) => item.id === request.params.id);
if (!post) {
throw app.httpErrors.notFound('Статья не найдена');
}
return post;
});Ответ тот же, а код короче. Есть и другие: badRequest() — 400, unauthorized() — 401, forbidden() — 403, conflict() — 409.
Свой обработчик ошибок
setErrorHandler задаёт функцию, через которую проходят все ошибки. Добавьте в src/app.js:
// src/app.js
app.setErrorHandler((error, request, reply) => {
const statusCode = error.statusCode ?? 500;
if (statusCode >= 500) {
request.log.error(error);
return reply.code(500).send({ error: 'Внутренняя ошибка сервера' });
}
return reply.code(statusCode).send({ error: error.message });
});Ошибки клиента (код 4xx) возвращаются с исходным сообщением, а ошибки сервера записываются в лог и отдаются клиенту без подробностей. Ошибки проверки схемы тоже приходят сюда — с кодом 400 и свойством error.validation.
Страница 404
Для адресов без маршрута есть отдельный обработчик:
// src/app.js
app.setNotFoundHandler((request, reply) => {
return reply.code(404).send({ error: `Адрес ${request.url} не найден` });
});http://localhost:3000/nothing вернёт {"error":"Адрес /nothing не найден"}.
Где действуют обработчики
Оба метода подчиняются инкапсуляции: вызванные в плагине, они действуют только на его маршруты. Например, у раздела /admin может быть своя страница 404.
Частая ошибка
Отдавать клиенту error.message для любых ошибок опасно: сообщение ошибки базы данных или кода может раскрыть имена таблиц, пути к файлам и другие детали. Для кода 500 отвечайте общей фразой, а подробности пишите в лог, как в примере выше.