Cómo utilizar los filtros de excepción de Nest.js para manejar errores

Los filtros de excepciones de Nest.js proporcionan una manera de interceptar y manejar excepciones globalmente o por controlador.

Le permiten centralizar la lógica de manejo de errores, formatear las respuestas de error y proporcionar un manejo de errores consistente en toda su aplicación. Obtenga información sobre los filtros de excepciones y cómo usarlos para manejar adecuadamente los errores de la aplicación.

Manejo de errores predeterminado en Nest.js

De forma predeterminada, Nest.js tiene una capa de excepción que se ocupa de cualquier excepción que el código de su aplicación no maneja.

Cuando ocurre un error no controlado en su aplicación, Nest.js lo detecta y devuelve un error interno del servidor 500 al cliente. El JSON que devuelve Nest.js en este caso se ve así:

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

Si el objeto de error que genera su código contiene un código de estado y un mensaje, Nest.js devolverá esos valores en lugar de la respuesta predeterminada.

Para evitar este comportamiento genérico y enviar una respuesta de error más significativa al cliente, debe manejar diligentemente todos los errores que puedan ocurrir en su aplicación. Puede lograr esto utilizando los filtros de excepción personalizados o integrados de Nest.js.

Crear un filtro de excepción personalizado

Para demostrar el proceso de creación de un filtro de excepciones personalizado, intente crear uno que maneje todas las excepciones HTTP.

Comience con un archivo llamado http.exception.ts y agréguele las siguientes importaciones:

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

import { Request, Response } from 'express';

Estas importaciones tienen los siguientes propósitos.

  • ExceptionFilter: esta es una interfaz que describe la implementación de un filtro de excepciones.
  • Catch: este es un decorador que marca una clase como filtro de excepción de Nest.
  • ArgumentsHost: esta interfaz proporciona métodos para recuperar los argumentos pasados ​​a un controlador. Le permite elegir el contexto de ejecución apropiado (por ejemplo, HTTP, RPC o WebSockets) para recuperar argumentos.
  • HttpException: esta es una clase que define la excepción HTTP base de Nest.
  • Solicitud y respuesta: estas son las interfaces para un objeto de solicitud y respuesta de Express.js, respectivamente.

A continuación, cree una clase, HttpExceptionFilter, que implemente ExceptionFilter. Anótelo con el decorador Catch para indicar que maneja HttpExceptions:

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

A continuación, complete la clase con este código:

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

Este bloque de código recupera los objetos de solicitud y respuesta del objeto ArgumentsHost y extrae información relevante de la excepción. Devuelve al cliente una respuesta de objeto JSON estructurado, con detalles sobre el error.

Filtros de excepción vinculantes

Puede vincular un filtro de excepción a un controlador o a toda su aplicación, según sus necesidades.

Para vincular un filtro de excepción globalmente, primero importe el filtro de excepción a su archivo main.ts. Luego, pasa una instancia de tu filtro de excepción al método 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();

Para vincular una excepción a un controlador, importe el decorador UseFilters y su filtro de excepción. Anota tu clase de controlador con el decorador @UseFilters y pasa una instancia de tu filtro de excepción como argumento al decorador:

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

El lugar donde vincule su filtro determinará el alcance de su manejo de errores. Los filtros vinculados al controlador solo atenderán al controlador al que lo vinculó, y los filtros vinculados a la aplicación atenderán a toda la aplicación.

Uso de excepciones integradas para generar errores

Nest.js proporciona clases de excepción integradas que puedes usar para generar errores.

Por ejemplo, puedes generar errores de código de estado 404 con la clase NotFoundException:

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

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

Este bloque de código utiliza una declaración condicional para verificar si el usuario determinado existe. De lo contrario, arroja un error 404 usando NotFoundException y pasando un mensaje como argumento.

Clases de excepción integradas comunes

Otras clases de excepción integradas incluyen, entre otras, las siguientes.

  • BadRequestException: lanza una excepción que indica una solicitud incorrecta con un código de estado de 400. Puede usar esta excepción cuando la solicitud del cliente no es válida o tiene un formato incorrecto y el servidor no puede procesarla debido a un error del cliente. Por lo general, implica que el cliente necesita modificar la solicitud para que sea válida.
  • UnauthorizedException: lanza una excepción que indica acceso no autorizado con un código de estado de 401. Puede usar esta excepción cuando un usuario no está autenticado o carece de los permisos necesarios para acceder a un recurso.
  • ForbiddenException: lanza una excepción que indica acceso prohibido con un código de estado de 403. Puede usar esta excepción cuando un usuario está autenticado pero no autorizado para realizar una acción específica.
  • RequestTimeoutException: genera una excepción que indica que se agotó el tiempo de espera de la solicitud con un código de estado de 408. Puede usar esta excepción cuando un servidor finaliza una solicitud porque tardó demasiado en procesarse.
  • ConflictException: lanza una excepción que indica un conflicto con un código de estado de 409. Puede usar esta excepción cuando hay un conflicto entre la solicitud del cliente y el estado actual del recurso, como cuando se intenta crear un recurso que ya existe.
  • InternalServerErrorException: genera una excepción que indica un error interno del servidor con un código de estado de 500. Puede usar esta excepción cuando ocurre un error inesperado en el lado del servidor, lo que indica que el servidor no puede cumplir con la solicitud debido a un problema interno.

Mejores prácticas para el manejo de errores en Nest.js

Al manejar errores en Nest.js, asegúrese de usar filtros de excepciones para detectar y manejar excepciones globalmente o por controlador. También puede crear filtros personalizados para tipos de excepción específicos.

Además, asegúrese de utilizar las clases de excepción integradas adecuadas para generar errores adecuados y significativos. Estas prácticas pueden mejorar significativamente la confiabilidad de tus aplicaciones Nest.js.