Filtry pro zpracování výjimek v Nest.js umožňují efektivně zachytávat a řešit chyby, a to jak globálně, tak i v rámci jednotlivých kontrolerů.
Díky nim je možné centralizovat logiku pro zpracování chyb, formátovat chybové zprávy a zajišťovat konzistentní přístup k chybám napříč celou aplikací. V následujícím textu se dozvíte více o filtrech výjimek a jak je využít pro správné zacházení s chybami ve vaší aplikaci.
Standardní zpracování chyb v Nest.js
Nest.js standardně disponuje vrstvou pro zpracování výjimek, která automaticky řeší všechny chyby, jež nejsou ošetřeny přímo ve vašem kódu aplikace.
Pokud ve vaší aplikaci dojde k neošetřené chybě, Nest.js ji zachytí a klientovi vrátí interní chybu serveru s kódem 500. Formát JSON, který Nest.js v tomto případě generuje, vypadá takto:
{
"statusCode": 500,
"message": "Internal server error"
}
V případě, že chybový objekt vyvolaný vaším kódem obsahuje vlastnosti statusCode a message, Nest.js použije tyto hodnoty namísto výchozí odpovědi.
Pro potlačení tohoto standardního chování a zaslání klientovi informativnější chybové zprávy je nezbytné pečlivě ošetřit všechny chyby, které mohou v aplikaci nastat. Toho lze dosáhnout s pomocí vestavěných nebo vlastních filtrů výjimek v Nest.js.
Vytvoření vlastního filtru výjimek
Pro demonstraci procesu vytvoření vlastního filtru výjimek si zkusíme vytvořit filtr, který bude zpracovávat všechny HTTP výjimky.
Nejprve vytvořte soubor s názvem http.exception.ts a vložte do něj následující importy:
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';import { Request, Response } from 'express';
Tyto importy slouží k následujícím účelům:
- ExceptionFilter: Toto rozhraní definuje implementaci filtru pro zpracování výjimek.
- Catch: Tento dekorátor označuje třídu jako filtr výjimek v rámci Nest.js.
- ArgumentsHost: Toto rozhraní poskytuje metody pro získání argumentů předaných handleru a umožňuje zvolit správný kontext (např. HTTP, RPC, WebSockets) pro získání argumentů.
- HttpException: Toto je třída definující základní HTTP výjimku v Nest.js.
- Request & Response: Tato rozhraní slouží pro práci s objekty požadavku a odpovědi v Express.js.
Dále vytvořte třídu HttpExceptionFilter, která bude implementovat rozhraní ExceptionFilter. Označte ji dekorátorem Catch, aby bylo jasné, že zpracovává HttpExceptions:
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {}
Následně doplňte třídu o následující kód:
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',
});
}
Tento kód získá objekty požadavku a odpovědi z ArgumentsHost a extrahuje z výjimky potřebné informace. Klientovi je poté odeslána strukturovaná JSON odpověď s detaily o chybě.
Navázání filtrů výjimek
Filtr výjimek můžete navázat na konkrétní kontroler nebo na celou aplikaci, dle vašich požadavků.
Pro globální navázání filtru výjimek nejprve naimportujte filtr do souboru main.ts. Poté předáte instanci vašeho filtru výjimek metodě 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();
Pro navázání filtru výjimek na konkrétní kontroler, importujte dekorátor UseFilters a váš filtr výjimek. Označte svou třídu kontroleru pomocí @UseFilters a jako argument dekorátoru předáte instanci vašeho filtru výjimek:
@Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}
Místo, kde filtr navážete, určí rozsah jeho působnosti. Filtry navázané na kontroler se starají pouze o chyby v daném kontroleru, zatímco filtry navázané na celou aplikaci zpracovávají chyby v celé aplikaci.
Využití vestavěných výjimek pro vyvolávání chyb
Nest.js nabízí vestavěné třídy výjimek, které můžete využít pro vyvolávání chyb.
Například pro vyvolání chyby 404, můžete použít třídu NotFoundException:
getUserById(id: number) {
const user = users.find((user) => user.id === id);if (!user) {
throw new NotFoundException({
message: `User with id ${id} not found`,
});
}
}
Tento kód za pomoci podmínky kontroluje, zda existuje uživatel se zadaným ID. Pokud ne, vyvolá se chyba 404 pomocí NotFoundException, přičemž je zpráva předána jako argument.
Časté vestavěné třídy výjimek
K dalším vestavěným třídám výjimek patří mimo jiné:
- BadRequestException: Vyvolává výjimku signalizující chybný požadavek (stavový kód 400). Tuto výjimku použijte, pokud je požadavek klienta neplatný nebo má špatný formát a server ho nemůže kvůli chybě na straně klienta zpracovat. To obvykle znamená, že klient musí svůj požadavek upravit.
- UnauthorizedException: Vyvolává výjimku signalizující neoprávněný přístup (stavový kód 401). Použijte ji, pokud uživatel není ověřen nebo nemá dostatečná oprávnění pro přístup k požadovanému zdroji.
- ForbiddenException: Vyvolává výjimku signalizující zakázaný přístup (stavový kód 403). Tuto výjimku použijte, pokud je uživatel sice ověřen, ale nemá oprávnění k provedení konkrétní akce.
- RequestTimeoutException: Vyvolává výjimku signalizující vypršení časového limitu požadavku (stavový kód 408). Použijte ji v případě, že server ukončí požadavek kvůli překročení časového limitu pro zpracování.
- ConflictException: Vyvolává výjimku signalizující konflikt (stavový kód 409). Použijte ji v případě konfliktu mezi požadavkem klienta a aktuálním stavem zdroje, například při pokusu o vytvoření zdroje, který již existuje.
- InternalServerErrorException: Vyvolává výjimku signalizující interní chybu serveru (stavový kód 500). Použijte ji, pokud dojde k neočekávané chybě na straně serveru, která zabrání úspěšnému zpracování požadavku.
Doporučené postupy pro zpracování chyb v Nest.js
Při zpracování chyb v Nest.js je vhodné využívat filtry výjimek pro zachytávání a zpracování výjimek, a to jak globálně, tak i pro jednotlivé kontrolery. Je také vhodné vytvářet si vlastní filtry pro konkrétní typy výjimek.
Dále nezapomínejte využívat vhodné vestavěné třídy výjimek pro vyvolávání srozumitelných chybových stavů. Tyto postupy mohou výrazně zlepšit spolehlivost vašich aplikací v Nest.js.