Come utilizzare i filtri delle eccezioni Nest.js per gestire gli errori

I filtri delle eccezioni Nest.js forniscono un modo per intercettare e gestire le eccezioni a livello globale o in base al controller.

Ti consentono di centralizzare la logica di gestione degli errori, formattare le risposte agli errori e fornire una gestione coerente degli errori in tutta l’applicazione. Informazioni sui filtri delle eccezioni e su come utilizzarli per gestire in modo appropriato gli errori dell’applicazione.

Gestione degli errori predefinita in Nest.js

Per impostazione predefinita, Nest.js dispone di un livello di eccezioni che gestisce eventuali eccezioni non gestite dal codice dell’applicazione.

Quando si verifica un errore non gestito nella tua applicazione, Nest.js lo rileva e restituisce al client un errore interno del server 500. Il JSON restituito da Nest.js in questo caso è simile al seguente:

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

Se l’oggetto errore generato dal codice contiene uno statusCode e un messaggio, Nest.js restituirà tali valori anziché la risposta predefinita.

Per evitare questo comportamento generico e inviare una risposta di errore più significativa al client, è necessario gestire con diligenza tutti gli errori che potrebbero verificarsi nella propria applicazione. Puoi ottenere questo risultato utilizzando i filtri delle eccezioni integrati o personalizzati di Nest.js.

Creazione di un filtro eccezioni personalizzato

Per dimostrare il processo di creazione di un filtro per eccezioni personalizzato, prova a crearne uno che gestirà tutte le eccezioni HTTP.

Inizia con un file chiamato http.exception.ts e aggiungivi le seguenti importazioni:

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

import { Request, Response } from 'express';

Queste importazioni servono ai seguenti scopi.

  • ExceptionFilter: questa è un’interfaccia che descrive l’implementazione di un filtro di eccezioni.
  • Catch: questo è un decoratore che contrassegna una classe come filtro di eccezioni Nest.
  • ArgumentsHost: questa interfaccia fornisce metodi per recuperare gli argomenti passati a un gestore. Ti consente di scegliere il contesto di esecuzione appropriato (ad esempio, HTTP, RPC o WebSocket) da cui recuperare gli argomenti.
  • HttpException: questa è una classe che definisce l’eccezione Nest HTTP di base.
  • Richiesta e risposta: queste sono le interfacce rispettivamente per una richiesta e un oggetto risposta Express.js.

Creare quindi una classe, HttpExceptionFilter, che implementi ExceptionFilter. Annotalo con il decoratore Catch per indicare che gestisce HttpExceptions:

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

Successivamente, compila la classe con questo codice:

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

Questo blocco di codice recupera gli oggetti di richiesta e risposta dall’oggetto ArgumentsHost ed estrae le informazioni rilevanti dall’eccezione. Restituisce al client una risposta di oggetto JSON strutturata, con i dettagli sull’errore.

Associazione dei filtri delle eccezioni

Puoi associare un filtro delle eccezioni a un controller o all’intera applicazione, a seconda delle tue esigenze.

Per associare un filtro di eccezioni a livello globale, importa prima il filtro di eccezioni nel file main.ts. Quindi, passa un’istanza del filtro delle eccezioni al metodo 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();

Per associare un’eccezione a un controller, importa il decoratore UseFilters e il filtro delle eccezioni. Annota la classe del controller con il decoratore @UseFilters e passa un’istanza del filtro delle eccezioni come argomento al decoratore:

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

Il punto in cui colleghi il filtro determinerà l’ambito della gestione degli errori. I filtri associati al controller si occuperanno solo del controller a cui lo hai associato, mentre i filtri associati all’applicazione si occuperanno dell’intera applicazione.

Utilizzo di eccezioni integrate per generare errori

Nest.js fornisce classi di eccezioni integrate che puoi utilizzare per generare errori.

Ad esempio, puoi generare errori di codice di stato 404 con la classe NotFoundException:

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

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

Questo blocco di codice utilizza un’istruzione condizionale per verificare se l’utente specificato esiste. In caso contrario, genera un errore 404 utilizzando NotFoundException, passando un messaggio come argomento.

Classi di eccezioni integrate comuni

Altre classi di eccezioni integrate includono, ma non sono limitate a, le seguenti.

  • BadRequestException: genera un’eccezione che indica una richiesta errata con un codice di stato 400. È possibile utilizzare questa eccezione quando la richiesta del client non è valida o non è valida e il server non può elaborarla a causa dell’errore del client. In genere implica che il client debba modificare la richiesta per renderla valida.
  • UnauthorizedException: genera un’eccezione che indica un accesso non autorizzato con un codice di stato 401. È possibile utilizzare questa eccezione quando un utente non è autenticato o non dispone delle autorizzazioni necessarie per accedere a una risorsa.
  • ForbiddenException: genera un’eccezione che indica un accesso vietato con un codice di stato 403. È possibile utilizzare questa eccezione quando un utente è autenticato ma non autorizzato a eseguire un’azione specifica.
  • RequestTimeoutException: genera un’eccezione che indica che la richiesta è scaduta con un codice di stato 408. È possibile utilizzare questa eccezione quando un server termina una richiesta perché ha impiegato troppo tempo per l’elaborazione.
  • ConflittException: genera un’eccezione che indica un conflitto con un codice di stato 409. È possibile utilizzare questa eccezione laddove esiste un conflitto tra la richiesta del client e lo stato corrente della risorsa, ad esempio quando si tenta di creare una risorsa che già esiste.
  • InternalServerErrorException: genera un’eccezione che indica un errore interno del server con un codice di stato 500. È possibile utilizzare questa eccezione quando si verifica un errore imprevisto sul lato server, indicando che il server non può soddisfare la richiesta a causa di un problema interno.

Best practice per la gestione degli errori in Nest.js

Quando gestisci gli errori in Nest.js, assicurati di utilizzare i filtri delle eccezioni per acquisire e gestire le eccezioni a livello globale o per controller. Puoi anche creare filtri personalizzati per tipi di eccezioni specifici.

Inoltre, assicurati di utilizzare le classi di eccezioni integrate appropriate per generare errori corretti e significativi. Queste pratiche possono migliorare in modo significativo l’affidabilità delle tue app Nest.js.