Så här använder du Nest.js undantagsfilter för att hantera fel

Nest.js undantagsfilter ger ett sätt att fånga upp och hantera undantag globalt eller per kontrollant.

De låter dig centralisera felhanteringslogiken, formatera felsvar och tillhandahålla konsekvent felhantering i hela din applikation. Lär dig mer om undantagsfilter och hur du använder dem för att hantera programfel på lämpligt sätt.

Standardfelhantering i Nest.js

Som standard har Nest.js ett undantagslager som hanterar eventuella undantag som din applikationskod inte hanterar.

När ett ohanterat fel uppstår i din applikation fångar Nest.js upp det och returnerar ett 500 internt serverfel till klienten. JSON som Nest.js returnerar i det här fallet ser ut så här:

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

Om felobjektet som din kod skickar innehåller en statusCode och ett meddelande kommer Nest.js att returnera dessa värden istället för standardsvaret.

För att undvika detta generiska beteende och skicka ett mer meningsfullt felsvar till klienten måste du noggrant hantera alla fel som kan uppstå i din applikation. Du kan uppnå detta med Nest.js inbyggda eller anpassade undantagsfilter.

Skapa ett anpassat undantagsfilter

För att demonstrera processen för att skapa ett anpassat undantagsfilter, försök att skapa ett som hanterar alla HTTP-undantag.

Börja med en fil som heter http.exception.ts och lägg till följande importer till den:

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

import { Request, Response } from 'express';

Denna import tjänar följande syften.

  • ExceptionFilter: Detta är ett gränssnitt som beskriver implementeringen av ett undantagsfilter.
  • Catch: Det här är en dekoratör som markerar en klass som ett Nest-undantagsfilter.
  • ArgumentsHost: Detta gränssnitt tillhandahåller metoder för att hämta argumenten som skickas till en hanterare. Det låter dig välja rätt exekveringskontext (t.ex. HTTP, RPC eller WebSockets) att hämta argument från.
  • HttpException: Det här är en klass som definierar det grundläggande Nest HTTP-undantaget.
  • Request & Response: Dessa är gränssnitten för ett Express.js-förfrågan respektive svarsobjekt.

Skapa sedan en klass, HttpExceptionFilter, som implementerar ExceptionFilter. Anteckna den med Catch-dekoratören för att indikera att den hanterar HttpExceptions:

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

Fyll sedan i klassen med denna kod:

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

Detta kodblock hämtar begäran och svarsobjekt från ArgumentsHost-objektet och extraherar relevant information från undantaget. Den returnerar ett strukturerat JSON-objektsvar, med detaljer om felet, till klienten.

Bindande undantagsfilter

Du kan binda ett undantagsfilter till en kontroller eller hela din applikation, beroende på dina behov.

För att binda ett undantagsfilter globalt, importera först undantagsfiltret till din main.ts-fil. Skicka sedan en instans av ditt undantagsfilter till metoden 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();

För att binda ett undantag till en kontrollenhet, importera UseFilters-dekoratören och ditt undantagsfilter. Annotera din kontrollklass med @UseFilters-dekoratören och skicka en instans av ditt undantagsfilter som ett argument till dekoratören:

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

Var du binder ditt filter kommer att avgöra omfattningen av din felhantering. Kontrollerbundna filter kommer bara att tillgodose kontrollenheten du kopplade den till, och programbundna filter kommer att tillgodose hela programmet.

Använda inbyggda undantag för att kasta fel

Nest.js tillhandahåller inbyggda undantagsklasser som du kan använda för att skicka fel.

Till exempel kan du skicka 404-statuskodfel med klassen NotFoundException:

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

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

Detta kodblock använder en villkorlig sats för att kontrollera om den givna användaren finns. Om inte, skickar den ett 404-fel med hjälp av NotFoundException och skickar ett meddelande som ett argument.

Vanliga inbyggda undantagsklasser

Andra inbyggda undantagsklasser inkluderar, men är inte begränsade till, följande.

  • BadRequestException: Kastar ett undantag som indikerar en felaktig begäran med en statuskod på 400. Du kan använda detta undantag när klientens begäran är ogiltig eller felaktig, och servern inte kan behandla den på grund av klientens fel. Det innebär vanligtvis att klienten måste ändra begäran för att göra den giltig.
  • UnauthorizedException: Kastar ett undantag som indikerar obehörig åtkomst med statuskoden 401. Du kan använda detta undantag när en användare inte är autentiserad eller saknar nödvändiga behörigheter för att komma åt en resurs.
  • ForbiddenException: Kastar ett undantag som indikerar förbjuden åtkomst med statuskoden 403. Du kan använda detta undantag när en användare är autentiserad men inte auktoriserad att utföra en specifik åtgärd.
  • RequestTimeoutException: Kastar ett undantag som indikerar att begäran har gått ut med en statuskod på 408. Du kan använda detta undantag när en server avslutar en begäran eftersom det tog för lång tid att behandla.
  • ConflictException: Kastar ett undantag som indikerar en konflikt med statuskoden 409. Du kan använda detta undantag där det finns en konflikt mellan klientens begäran och resursens aktuella tillstånd, till exempel när du försöker skapa en resurs som redan finns.
  • InternalServerErrorException: Kastar ett undantag som indikerar ett internt serverfel med statuskoden 500. Du kan använda detta undantag när ett oväntat fel inträffar på serversidan, vilket indikerar att servern inte kan uppfylla begäran på grund av ett internt problem.

Bästa metoder för felhantering i Nest.js

När du hanterar fel i Nest.js, se till att använda undantagsfilter för att fånga och hantera undantag globalt eller per kontrollenhet. Du kan också skapa anpassade filter för specifika undantagstyper.

Se dessutom till att du använder lämpliga inbyggda undantagsklasser för att skapa korrekta och meningsfulla fel. Dessa metoder kan avsevärt förbättra tillförlitligheten för dina Nest.js-appar.