Пошук уроків, статей та іншого контенту
Як NestJS перетворює викинуті винятки на HTTP-відповіді — і як налаштувати цей процес самостійно.
NestJS має вбудований шар, що перехоплює будь-який необроблений виняток, кинутий десь у процесі обробки запиту (контролер, сервіс, Pipe, Guard), і перетворює його на відповідну HTTP-відповідь. Для стандартних класів винятків NestJS (HttpException та похідні — NotFoundException, BadRequestException, UnauthorizedException) відповідь формується автоматично з правильним статус-кодом.
import { NotFoundException } from "@nestjs/common";
@Get(":id")
findOne(@Param("id") id: string) {
const cat = this.catsService.findOne(id);
if (!cat) {
throw new NotFoundException(`Кота з id ${id} не знайдено`);
// автоматично стає HTTP 404 з тілом { statusCode: 404, message: "..." }
}
return cat;
}Коли потрібна нестандартна поведінка — власний формат тіла помилки, логування конкретного типу помилок, обробка помилок, що не є HttpException (наприклад, помилка бібліотеки роботи з базою даних) — пишуть власний Exception Filter, позначений декоратором @Catch():
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from "@nestjs/common";
@Catch(HttpException)
export class CustomExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const status = exception.getStatus();
response.status(status).json({
timestamp: new Date().toISOString(),
path: ctx.getRequest().url,
message: exception.message,
});
}
}Ця ідея — централізований шар, що перехоплює й форматує помилки в одному місці замість обробки в кожному обробнику окремо, — та сама, що й у Node.js-уроці про обробку помилок (кастомні класи помилок зі statusCode) і в статті «N+1 Query Problem» сусідніх курсів: помилки заслуговують систематичного, а не ad hoc підходу.
Як і Pipes/Guards/Interceptors, Exception Filter можна підключити локально (@UseFilters() на метод чи контролер) або глобально при старті застосунку — глобальне підключення типове для узгодженого формату помилок по всьому API:
// main.ts
app.useGlobalFilters(new CustomExceptionFilter());Власний Exception Filter, підключений через @Catch(HttpException), обробляє лише HttpException та його підкласи — звичайна необроблена помилка JavaScript (наприклад, TypeError через звернення до undefined) пройде повз нього, якщо явно не додати @Catch() без аргументів для перехоплення геть усіх типів винятків.
Кидати звичайний Error замість HttpException/NotFoundException тощо там, де очікується конкретна HTTP-відповідь — NestJS не знає, який статус-код зіставити зі звичайним Error, і повертає загальний 500.
Писати @Catch(HttpException) і забувати, що звичайні необроблені винятки (не HttpException) не потраплять у цей фільтр — потрібен окремий catch-all фільтр для справді непередбачених помилок.
Розкривати внутрішні деталі помилки (стек виклику, повідомлення драйвера бази даних) у відповіді клієнту в продакшн-режимі — витік деталей реалізації, потенційно корисний зловмиснику.
NestJS автоматично перетворює викинуті HttpException (і похідні на кшталт NotFoundException) на відповідну HTTP-відповідь; власний Exception Filter (@Catch()) дозволяє налаштувати цей процес — власний формат тіла помилки, логування, обробку нестандартних типів винятків — централізовано, а не в кожному обробнику окремо.