При создании приложений с помощью NestJS обработка ошибок и реализация надежного ведения журнала являются важными аспектами обеспечения надежности и ремонтопригодности вашего приложения. В этом подробном руководстве мы рассмотрим лучшие практики обработки ошибок и ведения журнала в NestJS, специально предназначенные для начинающих. Итак, пристегните ремни и давайте отправимся в это путешествие, чтобы освоить обработку ошибок и регистрацию в NestJS!

Понимание обработки ошибок в NestJS

Обработка ошибок — это процесс изящной обработки и управления непредвиденными ситуациями, которые могут возникнуть во время выполнения вашего приложения. NestJS предлагает структурированный подход для эффективной обработки ошибок. Основным механизмом для достижения этого является использование фильтров исключений. Фильтры исключений позволяют перехватывать возникающие исключения и предпринимать соответствующие действия, например возвращать клиентам содержательные ответы об ошибках.

Давайте посмотрим, как реализовать фильтр исключений:

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

@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,
    });
  }
}

В этом примере мы создали HttpExceptionFilter, который перехватывает любые HttpException, которые могут возникнуть в нашем приложении. Затем он извлекает соответствующую информацию из исключения и отправляет клиенту структурированный ответ JSON, включая код состояния, отметку времени, путь запроса и сообщение об ошибке.

Чтобы применить этот фильтр глобально к вашему приложению, вы можете использовать метод app.useGlobalFilters() в файле main.ts:

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();

При такой настройке все HttpExceptions будут перехвачены нашим HttpExceptionFilter, что обеспечит согласованные ответы на ошибки во всем приложении.

Обработка пользовательских исключений

Хотя NestJS предоставляет несколько встроенных исключений, вы часто будете сталкиваться со сценариями, в которых вам нужно определить собственные исключения. Создание пользовательских исключений является простым и позволяет предоставить клиенту конкретные сведения об ошибке.

Допустим, мы хотим создать собственный NotFoundException:

export class NotFoundException extends HttpException {
  constructor(message: string) {
    super(message, HttpStatus.NOT_FOUND);
  }
}

Затем мы можем использовать это пользовательское исключение в службах или контроллерах нашего приложения:

import { Injectable, NotFoundException } from '@nestjs/common';
import { Task } from './interfaces/task.interface';

@Injectable()
export class TaskService {
  private tasks: Task[] = [];

  getTaskById(id: string): Task {
    const task = this.tasks.find((task) => task.id === id);
    if (!task) {
      throw new NotFoundException(`Task with ID ${id} not found.`);
    }
    return task;
  }
}

В этом примере, если запрошенная задача с конкретным id не найдена, мы выбрасываем NotFoundException, который будет перехвачен нашим глобальным HttpExceptionFilter. Это позволяет нам отправлять ответ клиенту, удобный для пользователя, без утечки конфиденциальных деталей реализации.

Вход в NestJS

Эффективное ведение журнала необходимо для мониторинга поведения вашего приложения и диагностики потенциальных проблем. NestJS предоставляет мощный механизм ведения журнала «из коробки», позволяя вам выбирать из различных уровней ведения журнала, средств форматирования журнала и транспорта.

По умолчанию NestJS использует класс Logger для обработки журналов приложений. Чтобы использовать регистратор по умолчанию в своих службах или контроллерах, вы можете внедрить его с помощью декоратора @Logger():

import { Injectable, Logger } from '@nestjs/common';

@Injectable()
export class TaskService {
  private logger = new Logger(TaskService.name);

  // ...

  someMethod() {
    this.logger.log('This is a log message.');
    this.logger.debug('Debugging some process...');
    this.logger.warn('Warning: Something seems off!');
    this.logger.error('Oops! An error occurred.');
  }
}

Класс Logger предоставляет методы для различных уровней журнала, таких как log, debug, warn и error. Каждый уровень журнала соответствует определенной серьезности, и вы можете настроить поведение журнала в своем приложении NestJS.

Настройка поведения ведения журнала

Если вам нужен больший контроль над поведением ведения журнала вашего приложения, NestJS позволяет создавать собственные регистраторы, реализуя интерфейс LoggerService.

Давайте создадим забавный пользовательский регистратор, который записывает журналы в файл, а также включает смайлики!

import { LoggerService } from '@nestjs/common';

export class EmojiLogger implements LoggerService {
  log(message: string) {
    this.writeToFile('📢 ' + message);
  }

  error(message: string, trace: string) {
    this.writeToFile('❌ ' + message);
    this.writeToFile('🔍 Stack Trace: ' + trace);
  }

  warn(message: string) {
    this.writeToFile('⚠️ ' + message);
  }

  debug(message: string) {
    this.writeToFile('🐞 ' + message);
  }

  private writeToFile(message: string) {
    // Implement the logic to write logs to a file here.
    console.log(message); // For demonstration purposes, we'll just log to the console.
  }
}

Теперь, чтобы использовать наш EmojiLogger, давайте обновим файл main.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { EmojiLogger } from './emoji-logger';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: new EmojiLogger() });
  await app.listen(3000);
}
bootstrap();

С этой настройкой наше приложение будет использовать забавный EmojiLogger для регистрации сообщений. Не стесняйтесь настраивать метод writeToFile для записи журналов в файл или в любое другое предпочтительное место.

Заключение

В этой статье мы рассмотрели лучшие практики обработки ошибок и ведения журнала в NestJS. Мы узнали, как использовать фильтры исключений для корректной обработки ошибок и отправки клиентам структурированных ответов об ошибках. Кроме того, мы увидели, как создавать собственные исключения для более конкретных отчетов об ошибках. Кроме того, мы углубились в мир журналирования и узнали, как использовать класс Logger по умолчанию и создавать собственные регистраторы, такие как наш EmojiLogger.

Освоив обработку ошибок и ведение журнала в NestJS, вы уже на пути к созданию надежных и надежных приложений. Так что продолжайте экспериментировать, оставайтесь любопытными и получайте удовольствие от написания кода! 🚀🌟