Як використовувати фільтри винятків Nest.js для обробки помилок

Фільтри винятків Nest.js надають спосіб перехоплювати та обробляти винятки глобально або на основі кожного контролера.

Вони дозволяють централізувати логіку обробки помилок, форматувати відповіді на помилки та забезпечити послідовну обробку помилок у вашій програмі. Дізнайтеся про фільтри винятків і про те, як їх використовувати для відповідної обробки помилок програми.

Обробка помилок за замовчуванням у Nest.js

За замовчуванням у Nest.js є рівень винятків, який обробляє будь-які винятки, які не обробляє код програми.

Коли у вашій програмі виникає необроблена помилка, Nest.js виявляє її та повертає клієнту внутрішню помилку сервера 500. JSON, який Nest.js повертає в цьому випадку, виглядає так:

 {
  "statusCode": 500,
  "message": "Internal server error"
}

Якщо об’єкт помилки, який видає ваш код, містить statusCode і повідомлення, Nest.js поверне ці значення замість відповіді за замовчуванням.

Щоб уникнути такої загальної поведінки та надіслати клієнту більш значущу відповідь про помилку, вам потрібно ретельно обробляти всі помилки, які можуть виникати у вашій програмі. Ви можете досягти цього за допомогою вбудованих або спеціальних фільтрів винятків Nest.js.

Створення спеціального фільтра винятків

Щоб продемонструвати процес створення спеціального фільтра винятків, спробуйте створити такий, який оброблятиме всі винятки HTTP.

Почніть із файлу під назвою http.exception.ts і додайте до нього наступні елементи імпорту:

 import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
} from '@nestjs/common';

import { Request, Response } from 'express';

Цей імпорт служить для наступних цілей.

  • ExceptionFilter: це інтерфейс, що описує впровадження фільтра винятків.
  • Перешкода: це декоратор, який позначає клас як фільтр винятків Nest.
  • ArgumentsHost: цей інтерфейс надає методи для отримання аргументів, переданих обробнику. Це дозволяє вибрати відповідний контекст виконання (наприклад, HTTP, RPC або WebSockets) для отримання аргументів.
  • HttpException: це клас, який визначає базовий виняток HTTP Nest.
  • Запит і відповідь: це інтерфейси для об’єкта запиту та відповіді Express.js відповідно.
  Як створити воронкову діаграму в Excel

Далі створіть клас HttpExceptionFilter, який реалізує ExceptionFilter. Додайте до нього декоратор Catch, щоб вказати, що він обробляє HttpExceptions:

 @Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {}

Далі заповніть клас таким кодом:

 catch(exception: HttpException, host: ArgumentsHost) {
    
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();

    
    const request = ctx.getRequest<Request>();

    
    const status = exception.getStatus();

    
    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      message:
        exception.message
       || exception.getResponse()['message']
       || 'Internal Server Error',
    });
}

Цей блок коду отримує об’єкти запиту та відповіді з об’єкта ArgumentsHost і витягує відповідну інформацію з винятку. Він повертає клієнту структуровану відповідь об’єкта JSON із детальною інформацією про помилку.

Фільтри прив’язки винятків

Ви можете прив’язати фільтр винятків до контролера або всієї програми, залежно від ваших потреб.

Щоб пов’язати фільтр винятків глобально, спочатку імпортуйте фільтр винятків у файл main.ts. Потім передайте екземпляр свого фільтра винятків у метод app.useGlobalFilters:

 
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './exception/http.exception';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  
  app.useGlobalFilters(new HttpExceptionFilter());

  await app.listen(4050);
}

bootstrap();

Щоб зв’язати винятки з контролером, імпортуйте декоратор UseFilters і ваш фільтр винятків. Позначте свій клас контролера за допомогою декоратора @UseFilters і передайте екземпляр свого фільтра винятків як аргумент декоратору:

 @Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}

Місце, де ви прив’язуєте свій фільтр, визначатиме область обробки помилок. Фільтри, прив’язані до контролера, обслуговуватимуть лише той контролер, до якого ви його прив’язали, а фільтри, пов’язані з програмою, – для всієї програми.

  Як об’єднати або згрупувати кругові діаграми в Microsoft Excel

Використання вбудованих винятків для створення помилок

Nest.js містить вбудовані класи винятків, які можна використовувати для викиду помилок.

Наприклад, ви можете створити помилку коду стану 404 за допомогою класу NotFoundException:

   getUserById(id: number) {
    const user = users.find((user) => user.id === id);

    if (!user) {
      throw new NotFoundException({
        message: `User with id ${id} not found`,
      });
    }
  }

Цей блок коду використовує умовний оператор, щоб перевірити, чи існує даний користувач. Якщо ні, він видає помилку 404 за допомогою NotFoundException, передаючи повідомлення як аргумент.

Загальні вбудовані класи винятків

Інші вбудовані класи винятків включають, але не обмежуються ними, наступне.

  • BadRequestException: створює виняток, що вказує на неправильний запит із кодом статусу 400. Ви можете використовувати цей виняток, коли запит клієнта недійсний або неправильно сформований, і сервер не може обробити його через помилку клієнта. Зазвичай це означає, що клієнт повинен змінити запит, щоб зробити його дійсним.
  • UnauthorizedException: створює виняток, що вказує на неавторизований доступ із кодом статусу 401. Ви можете використовувати цей виняток, коли користувач не пройшов автентифікацію або не має необхідних дозволів для доступу до ресурсу.
  • ForbiddenException: створює виняток, який вказує на заборонений доступ із кодом статусу 403. Ви можете використовувати цей виняток, коли користувач автентифікований, але не авторизований для виконання певної дії.
  • RequestTimeoutException: створює виняток, який вказує на те, що час очікування запиту минув із кодом статусу 408. Ви можете використовувати цей виняток, коли сервер завершує запит, оскільки його обробка зайняла занадто багато часу.
  • ConflictException: створює виняток, що вказує на конфлікт із кодом статусу 409. Ви можете використовувати цей виняток, якщо є конфлікт між запитом клієнта та поточним станом ресурсу, наприклад, під час спроби створити ресурс, який уже існує.
  • InternalServerErrorException: створює виняток, який вказує на внутрішню помилку сервера з кодом стану 500. Ви можете використовувати цей виняток, коли на стороні сервера виникає неочікувана помилка, яка вказує на те, що сервер не може виконати запит через внутрішню проблему.
  10 найкращих класичних 2D-ігор, які змусять вас ностальгувати [2023]

Найкращі методи обробки помилок у Nest.js

Під час обробки помилок у Nest.js обов’язково використовуйте фільтри винятків, щоб перехоплювати та обробляти винятки глобально або для кожного контролера. Ви також можете створити власні фільтри для певних типів винятків.

Крім того, переконайтеся, що ви використовуєте відповідні вбудовані класи винятків, щоб створювати належні та значущі помилки. Ці методи можуть значно підвищити надійність ваших програм Nest.js.