Необработанные исключения могут вызвать путаницу и разочарование. Очистите их с помощью фильтров исключений.
Фильтры исключений Nest.js позволяют перехватывать и обрабатывать исключения глобально или для каждого контроллера.
Они позволяют централизовать логику обработки ошибок, форматировать ответы на ошибки и обеспечивать согласованную обработку ошибок во всем приложении. Узнайте о фильтрах исключений и о том, как их использовать для правильной обработки ошибок приложений.
Обработка ошибок по умолчанию в Nest.js
По умолчанию в Nest.js есть уровень исключений, который обрабатывает любые исключения, которые не обрабатывает код вашего приложения.
Когда в вашем приложении возникает необработанная ошибка, Nest.js перехватывает ее и возвращает клиенту внутреннюю ошибку сервера 500. JSON, который возвращает Nest.js в этом случае, выглядит следующим образом:
{
"statusCode": 500,
"message": "Internal server error"
}
Если объект ошибки, который выдает ваш код, содержит код статуса и сообщение, Nest.js вернет эти значения вместо ответа по умолчанию.
Чтобы избежать такого общего поведения и отправить клиенту более содержательный ответ об ошибке, вам необходимо тщательно обрабатывать все ошибки, которые могут возникнуть в вашем приложении. Этого можно добиться, используя встроенные или настраиваемые фильтры исключений Nest.js.
Создание пользовательского фильтра исключений
Чтобы продемонстрировать процесс создания собственного фильтра исключений, попробуйте создать фильтр, который будет обрабатывать все исключения HTTP.
Начните с файла с именем http.Exception.ts и добавьте в него следующий импорт:
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from'@nestjs/common';
import { Request, Response } from'express';
Этот импорт служит следующим целям.
- Фильтр исключений: это интерфейс, описывающий реализацию фильтра исключений.
- Ловить: это декоратор, который помечает класс как фильтр исключений Nest.
- АргументыХост: этот интерфейс предоставляет методы для получения аргументов, переданных обработчику. Он позволяет вам выбрать соответствующий контекст выполнения (например, HTTP, RPC или WebSockets) для получения аргументов.
- HttpException: это класс, определяющий базовое HTTP-исключение Nest.
- Запрос & Ответ: это интерфейсы для объекта запроса и ответа Express.js соответственно.
Далее создайте класс, HttpExceptionФильтр, который реализует Фильтр исключений. Прокомментируйте это с помощью Ловить декоратор, указывающий, что он обрабатывает HttpExceptions:
@Catch(HttpException)
exportclassHttpExceptionFilterimplementsExceptionFilter{}
Затем заполните класс этим кодом:
catch(exception: HttpException, host: ArgumentsHost) {
// Get the response object from the arguments host
const ctx = host.switchToHttp();
const response = ctx.getResponse(); // Get the request object from the arguments host
const request = ctx.getRequest(); // Get the status code from the exception
const status = exception.getStatus();
// Send a JSON response using the response object
response.status(status).json({
statusCode: status,
timestamp: newDate().toISOString(),
path: request.url,
message:
exception.message
|| exception.getResponse()['message']
|| 'Internal Server Error',
});
}
Этот блок кода извлекает объекты запроса и ответа из объекта ArgumentsHost и извлекает соответствующую информацию из исключения. Он возвращает клиенту структурированный ответ объекта JSON с подробной информацией об ошибке.
Привязка фильтров исключений
Вы можете привязать фильтр исключений к контроллеру или ко всему приложению, в зависимости от ваших потребностей.
Чтобы привязать фильтр исключений глобально, сначала импортируйте фильтр исключений в свою main.ts файл. Затем передайте экземпляр фильтра исключений в app.useGlobalFilters метод:
// main.ts
import { NestFactory } from'@nestjs/core';
import { AppModule } from'./app.module';
import { HttpExceptionFilter } from'./exception/http.exception';asyncfunctionbootstrap() {
const app = await NestFactory.create(AppModule);// Bind filter to the application
app.useGlobalFilters(new HttpExceptionFilter());await app.listen(4050);
}
bootstrap();
Чтобы привязать исключение к контроллеру, импортируйте ИспользованиеФильтры декоратор и ваш фильтр исключений. Аннотируйте свой класс контроллера с помощью @UseFilters декоратору и передайте экземпляр фильтра исключений в качестве аргумента декоратору:
@Controller()
@UseFilters(new HttpExceptionFilter())
exportclassAppController{}
Место привязки фильтра будет определять объем обработки ошибок. Фильтры, привязанные к контроллеру, будут обслуживать только тот контроллер, к которому вы его привязали, а фильтры, привязанные к приложению, будут обслуживать все приложение.
Использование встроенных исключений для выдачи ошибок
Nest.js предоставляет встроенные классы исключений, которые можно использовать для выдачи ошибок.
Например, вы можете выдать 404 ошибки кода состояния с NotFoundException сорт:
getUserById(id: number) {
const user = users.find((user) => user.id id);
if (!user) {
thrownew NotFoundException({
message: `User with id ${id} not found`,
});
}
}
Этот блок кода использует условное утверждение чтобы проверить, существует ли данный пользователь. Если нет, он выдает ошибку 404, используя NotFoundException, передавая сообщение в качестве аргумента.
Общие встроенные классы исключений
Другие встроенные классы исключений включают, помимо прочего, следующие.
- Бадрекуестисключение: выдает исключение, указывающее на неверный запрос с кодом состояния 400. Вы можете использовать это исключение, когда запрос клиента недействителен или имеет неверный формат и сервер не может его обработать из-за ошибки клиента. Обычно это подразумевает, что клиенту необходимо изменить запрос, чтобы сделать его действительным.
- Несанкционированное исключение: выдает исключение, указывающее несанкционированный доступ с кодом состояния 401. Вы можете использовать это исключение, если пользователь не прошел проверку подлинности или не имеет необходимых разрешений для доступа к ресурсу.
- Запрещенное исключение: выдает исключение, указывающее запрещенный доступ с кодом состояния 403. Вы можете использовать это исключение, когда пользователь аутентифицирован, но не авторизован для выполнения определенного действия.
- RequestTimeoutException: выдает исключение, указывающее, что время ожидания запроса истекло, с кодом состояния 408. Вы можете использовать это исключение, когда сервер завершает запрос, поскольку его обработка заняла слишком много времени.
- КонфликтИсключение: выдает исключение, указывающее на конфликт с кодом состояния 409. Это исключение можно использовать в случае конфликта между запросом клиента и текущим состоянием ресурса, например при попытке создать уже существующий ресурс.
- ВнутреннееисключениеServerErrorException: выдает исключение, указывающее на внутреннюю ошибку сервера, с кодом состояния 500. Вы можете использовать это исключение, когда на стороне сервера возникает непредвиденная ошибка, указывающая, что сервер не может выполнить запрос из-за внутренней проблемы.
Лучшие практики обработки ошибок в Nest.js
При обработке ошибок в Nest.js обязательно используйте фильтры исключений для перехвата и обработки исключений глобально или для каждого контроллера. Вы также можете создавать собственные фильтры для определенных типов исключений.
Кроме того, убедитесь, что вы используете соответствующие встроенные классы исключений для выдачи правильных и значимых ошибок. Эти методы могут значительно повысить надежность ваших приложений Nest.js.