Πώς να χρησιμοποιήσετε τα φίλτρα εξαίρεσης 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: Πρόκειται για μια διεπαφή που περιγράφει την υλοποίηση ενός φίλτρου εξαίρεσης.
  • Catch: Αυτό είναι ένα διακοσμητικό που επισημαίνει μια τάξη ως φίλτρο εξαίρεσης Nest.
  • ArgumentsHost: Αυτή η διεπαφή παρέχει μεθόδους για την ανάκτηση των ορισμάτων που διαβιβάζονται σε έναν χειριστή. Σας επιτρέπει να επιλέξετε το κατάλληλο περιβάλλον εκτέλεσης (π.χ. HTTP, RPC ή WebSockets) για να ανακτήσετε ορίσματα.
  • HttpException: Αυτή είναι μια κλάση που ορίζει τη βασική εξαίρεση Nest HTTP.
  • Request & Response: Αυτές είναι οι διεπαφές για ένα αντικείμενο αίτησης και απάντησης Express.js, αντίστοιχα.
  Πώς να δοκιμάσετε το PSU με πολύμετρο

Στη συνέχεια, δημιουργήστε μια κλάση, το 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 {}

Το σημείο που δεσμεύετε το φίλτρο σας θα καθορίσει το εύρος του χειρισμού των σφαλμάτων σας. Τα φίλτρα που συνδέονται με τον ελεγκτή θα εξυπηρετούν μόνο τον ελεγκτή στον οποίο τον δεσμεύσατε και τα φίλτρα που συνδέονται με την εφαρμογή θα εξυπηρετούν ολόκληρη την εφαρμογή.

  Πιθανότατα δεν θα λάβετε 25 $ από τη ρύθμιση περιορισμού του iPhone της Apple

Χρήση ενσωματωμένων εξαιρέσεων για την απόρριψη σφαλμάτων

Το 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. Μπορείτε να χρησιμοποιήσετε αυτήν την εξαίρεση όταν παρουσιαστεί ένα απροσδόκητο σφάλμα στην πλευρά του διακομιστή, το οποίο υποδεικνύει ότι ο διακομιστής δεν μπορεί να εκπληρώσει το αίτημα λόγω εσωτερικού ζητήματος.
  Πώς να αποκλείσετε έναν ιστότοπο στο Safari

Βέλτιστες πρακτικές για τον χειρισμό σφαλμάτων στο Nest.js

Κατά τον χειρισμό σφαλμάτων στο Nest.js, φροντίστε να χρησιμοποιείτε φίλτρα εξαιρέσεων για να εντοπίζετε και να χειρίζεστε εξαιρέσεις καθολικά ή ανά ελεγκτή. Μπορείτε επίσης να δημιουργήσετε προσαρμοσμένα φίλτρα για συγκεκριμένους τύπους εξαιρέσεων.

Επιπλέον, βεβαιωθείτε ότι χρησιμοποιείτε τις κατάλληλες ενσωματωμένες κλάσεις εξαιρέσεων για τη δημιουργία σωστών και ουσιαστικών σφαλμάτων. Αυτές οι πρακτικές μπορούν να βελτιώσουν σημαντικά την αξιοπιστία των εφαρμογών σας Nest.js.