Jak używać filtrów wyjątków Nest.js do obsługi błędów?
Filtry wyjątków Nest.js zapewniają sposób na przechwytywanie i obsługę wyjątków globalnie lub na podstawie kontrolera.
Centralizacja logiki obsługi błędów umożliwia programistom usprawnienie procesów poprzez konsolidację całego kodu związanego z błędami w jednym miejscu. Takie podejście nie tylko upraszcza rozwiązywanie problemów, ale także pozwala na bardziej uporządkowaną prezentację komunikatów o błędach użytkownikom końcowym. Wykorzystując filtry wyjątków, programiści mogą efektywnie zarządzać błędami występującymi w aplikacji, zapewniając spójny mechanizm reagowania, który zapewnia spójność w całym systemie.
Domyślna obsługa błędów w Nest.js
Nest.js zawiera wbudowany mechanizm obsługi wyjątków, który zajmuje się nieobsługiwanymi wyjątkami generowanymi przez kod aplikacji.
Rzeczywiście, gdy wyjątek pozostaje niezauważony podczas działania aplikacji opracowanej przy użyciu frameworka Nest.js, system automatycznie odpowiada kodem stanu HTTP 500 Internal Server Error wraz z predefiniowanym ładunkiem JSON zawierającym informacje o wystąpieniu błędu. Format ten został zaprojektowany z myślą o łatwej obsłudze przez programistów, którzy mogą łatwo prześledzić przyczynę problemu na podstawie dostarczonych szczegółów.
{
"statusCode": 500,
"message": "Internal server error"
}
Jeśli obiekt błędu wyrzucony przez kod zawiera zarówno kod stanu, jak i komunikat, Nest.js wykorzysta te wartości zamiast dostarczać standardową odpowiedź.
Aby zapobiec ogólnej obsłudze błędów i zamiast tego zapewnić klientom bardziej informacyjną odpowiedź, ważne jest, aby starannie zarządzać wszystkimi potencjalnymi błędami w aplikacji. Można to osiągnąć, wykorzystując istniejące filtry wyjątków Nest.js lub tworząc niestandardowe filtry dostosowane do konkretnych potrzeb.
Tworzenie niestandardowego filtra wyjątków
Aby zilustrować procedurę tworzenia niestandardowego filtra wyjątków, spróbuj skonstruować taki, który może obsługiwać wszystkie wyjątki HTTP.
Rozważ rozpoczęcie od dokumentu zatytułowanego “http.exception.ts”, a następnie włączenie do niego kolejnych instrukcji importu:
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
Importy te służą następującym celom.
Filtr wyjątków, zaimplementowany za pomocą tego interfejsu, służy do przechwytywania i obsługi wyjątków występujących podczas wykonywania programu.
Dekorator Catch oznacza oznaczenie klasy jako mechanizmu filtrowania wyjątków w ramach frameworka Nest.
Interfejs ArgumentsHost
przedstawia zestaw metod, które ułatwiają pozyskiwanie argumentów przekazywanych do określonej obsługi. Korzystając z tej struktury, można wybrać odpowiedni kontekst wykonania, taki jak HTTP, RPC lub WebSockets, w celu wyodrębnienia wspomnianych argumentów.
Wyjątek HttpException
stanowi podstawę wszystkich wyjątków HTTP Nest, obejmując znormalizowaną strukturę obsługi błędów w aplikacjach internetowych.
obiekty żądania i odpowiedzi. Pierwszy z nich reprezentuje przychodzące żądania klientów, podczas gdy drugi służy do wysyłania odpowiedzi na te żądania.
Aby zaimplementować filtr wyjątków do obsługi wyjątków HttpException
w naszej aplikacji ASP.NET Core, możemy utworzyć nową klasę o nazwie HttpExceptionFilter
. Klasa ta powinna dziedziczyć po ExceptionFilterAttribute
i być opatrzona atrybutem Catch
w celu obsługi wyjątków tego typu.
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {}
Następnie wypełnij klasę tym kodem:
catch(exception: HttpException, host: ArgumentsHost) {
// Get the response object from the arguments host
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
// Get the request object from the arguments host
const request = ctx.getRequest<Request>();
// Get the status code from the exception
const status = exception.getStatus();
// Send a JSON response using the response object
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message:
exception.message
|| exception.getResponse()['message']
|| 'Internal Server Error',
});
}
Obecna implementacja pobiera parametry żądania i odpowiedzi z instancji ArgumentsHost i analizuje wyjątki pod kątem istotnych danych. Rezultatem jest zorganizowana odpowiedź w formacie JSON zawierająca treść informacyjną dotyczącą błędu, która jest przekazywana do użytkownika końcowego.
Wiązanie filtrów wyjątków
Masz możliwość zastosowania filtra wyjątków na poziomie poszczególnych kontrolerów lub w całej aplikacji, w zależności od tego, co najlepiej odpowiada Twoim wymaganiom.
Aby zastosować globalny filtr wyjątków uniwersalnie, początkowo włącz filtr wyjątków do głównego main.ts
pliku. Następnie należy przedstawić instancję filtru wyjątków w metodzie app.useGlobalFilters()
.
// main.ts
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);
// Bind filter to the application
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(4050);
}
bootstrap();
Aby powiązać wyjątek z kontrolerem, konieczne jest zastosowanie dekoratora “UseFilters” wraz z odpowiednim filtrem wyjątków. Proces ten polega na zaimportowaniu dekoratora “UseFilters” i określonego filtru wyjątków. Następnie klasa kontrolera musi zostać opatrzona adnotacją przy użyciu dekoratora “@UseFilters”, jednocześnie przekazując instancję filtra wyjątków jako argument do dekoratora.
@Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}
Lokalizacja, w której filtr jest stosowany, dyktuje jego zakres możliwości obsługi błędów. Jeśli filtr jest powiązany z określonym kontrolerem, będzie miał zastosowanie wyłącznie do tego konkretnego kontrolera, podczas gdy filtr obejmujący całą aplikację będzie obejmował całą aplikację.
Używanie wbudowanych wyjątków do rzucania błędów
Nest.js oferuje szereg predefiniowanych kategorii wyjątków, które można wykorzystać do rzucania błędów, które mają na celu uproszczenie obsługi błędów i usprawnienie tworzenia aplikacji poprzez zapewnienie znormalizowanego podejścia do zarządzania wyjątkami w zorganizowany sposób.
Rzeczywiście, można wykorzystać klasę NotFoundException
do generowania błędu kodu statusu 404 w odpowiedzi na żądania, które nie mogą zostać spełnione przez serwer. Wyjątek ten jest powszechnie używany, gdy podejmowana jest próba uzyskania dostępu do zasobu lub strony, która nie istnieje na serwerze. Rzucając ten wyjątek, serwer może wskazać klientowi, że żądana zawartość jest niedostępna i dostarczyć informacji o tym, dlaczego żądanie nie powiodło się.
getUserById(id: number) {
const user = users.find((user) => user.id === id);
if (!user) {
throw new NotFoundException({
message: `User with id ${id} not found`,
});
}
}
Powyższy segment kodu wykorzystuje wyrażenie warunkowe do sprawdzenia, czy określony użytkownik jest obecny. W przypadku jego nieobecności zgłasza wyjątek 404, wykorzystując klasę NotFoundException i dostarczając odpowiedni komunikat jako argument.
Wspólne wbudowane klasy wyjątków
Dodatkowe predefiniowane kategorie wyjątków obejmują, ale nie ograniczają się do następujących przykładów.
BadRequestException
jest wyspecjalizowanym wyjątkiem w rozwoju oprogramowania, który reprezentuje odpowiedź HTTP z kodem stanu 400. Wyjątek ten jest zgłaszany, gdy żądanie klienta zostanie uznane przez serwer za nieprawidłowe lub nieprawidłowo sformatowane, co uniemożliwia jego przetworzenie. Główną implikacją tego wyjątku jest to, że klient musi odpowiednio dostosować swoje żądanie, aby naprawić wszelkie błędy lub nieprawidłowości.
Klasa UnauthorizedException
rzuca wyjątek oznaczający nieautoryzowany dostęp, któremu towarzyszy kod stanu HTTP 401. Wyjątek ten może zostać rzucony w sytuacji, gdy użytkownik nie został uwierzytelniony lub nie posiada wymaganych uprawnień do uzyskania dostępu do określonego zasobu.
Klasa ForbiddenException
reprezentuje wyjątek oznaczający nieautoryzowany dostęp, któremu towarzyszy kod stanu HTTP 403. Wyjątek ten może zostać rzucony w sytuacjach, w których użytkownik został pomyślnie uwierzytelniony, ale nie ma uprawnień niezbędnych do wykonania określonej operacji.
RequestTimeoutException
to wyjątek oparty na Javie, który jest rzucany, gdy żądanie przekroczyło określony limit czasu, co skutkuje kodem stanu HTTP 408. Ten wyjątek może być używany przez serwery do kończenia żądań, których przetworzenie zajęło więcej czasu niż oczekiwano.
Klasa ConflictException
reprezentuje wyjątek, który występuje z powodu konfliktu w kodzie stanu 409. Ten typ wyjątku może zostać rzucony, gdy żądanie klienta jest sprzeczne z obecnym stanem obsługiwanego zasobu, na przykład podczas próby utworzenia zasobu, który został już utworzony.
InternalServerErrorException
to typ wyjątku, który reprezentuje nieprzewidziany błąd występujący w infrastrukturze po stronie serwera, skutkujący niemożnością wykonania żądanego zadania. Ten konkretny wyjątek ma powiązany kod stanu HTTP 500 i powinien być wykorzystywany za każdym razem, gdy po stronie serwera pojawia się nieoczekiwany problem, który uniemożliwia mu spełnienie wymagań klienta.
Najlepsze praktyki obsługi błędów w Nest.js
Aby skutecznie zarządzać błędami w aplikacji Nest.js, ważne jest, aby korzystać z filtrów wyjątków, które przechwytują wyjątki globalne lub te, które są specyficzne dla poszczególnych kontrolerów. Dodatkowo można utworzyć niestandardowe filtry wyjątków dostosowane do określonych typów błędów.
Co więcej, kluczowe znaczenie ma wykorzystanie odpowiednich wbudowanych klas wyjątków do generowania dokładnych i istotnych komunikatów o błędach. Takie podejście znacząco przyczynia się do zwiększenia niezawodności aplikacji Nest.js.