如何使用 Nest.js 異常過濾器來處理錯誤
Nest.js 異常過濾器提供了一種全域或基於每個控制器攔截和處理異常的方法。
集中錯誤處理邏輯使開發人員能夠透過將所有與錯誤相關的程式碼整合到一個地方來簡化流程。這種方法不僅簡化了故障排除,而且還可以更有條理地向最終用戶呈現錯誤訊息。透過利用異常過濾器,開發人員可以有效管理應用程式中發生的錯誤,提供內聚的回應機制,確保整個系統的一致性。
Nest.js 中的預設錯誤處理
Nest.js 包含一個內建的異常處理機制,用於處理應用程式程式碼產生的未處理的異常。
事實上,當使用 Nest.js 框架開發的應用程式在運行時未註意到異常時,系統會自動回應 HTTP 狀態碼 500 內部伺服器錯誤以及包含有關錯誤發生的資訊的預定義 JSON 負載。這種格式旨在方便開發人員使用,他們可以根據提供的詳細資訊輕鬆追溯到問題的原因。
{
"statusCode": 500,
"message": "Internal server error"
}
如果程式碼拋出的錯誤物件同時包含狀態碼和訊息,Nest.js 將利用這些值,而不是提供標準回應。
為了防止對錯誤進行通用處理並向客戶提供更豐富的回應,仔細管理應用程式中的所有潛在錯誤非常重要。這可以透過利用 Nest.js 預先存在的異常過濾器或根據您的特定需求建立自訂過濾器來完成。
建立自訂異常過濾器
為了說明開發自訂異常過濾器的過程,請嘗試建立一個可以解決所有 HTTP 異常的過濾器。
考慮從名為「http.exception.ts」的文件開始,然後將後續導入語句合併到其中:
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
這些進口有以下目的。
透過此介面實現的異常過濾器用於捕獲和處理程序執行期間發生的異常。
Catch 裝飾器表示將類別指定為 Nest 框架內的異常過濾機制。
ArgumentsHost
介面提供了一組方法,有助於取得傳遞給特定處理程序的參數。透過利用這個框架,人們可以選擇適當的執行上下文,例如 HTTP、RPC 或 WebSockets,以便從中提取所述參數。
HttpException
代表所有 Nest HTTP 異常的基礎,包含用於處理 Web 應用程式中的錯誤的標準化結構。
請求和回應對象。前者代表傳入的客戶端請求,而後者用於發回對這些請求的回應。
為了在 ASP.NET Core 應用程式中實作處理 HttpException 的例外篩選器,我們可以建立一個名為 HttpExceptionFilter 的新類別。該類別應繼承自 ExceptionFilterAttribute 並使用 Catch 屬性進行註解以處理此類異常。
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {}
接下來,使用以下程式碼填充該類別:
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',
});
}
本實作從 ArgumentsHost 實例取得請求和回應參數,並分析相關資料的異常。結果是一個有組織的 JSON 格式的回复,其中包含有關轉發給最終用戶的錯誤的資訊內容。
綁定異常過濾器
您可以選擇在單一控制器層級或整個應用程式中套用異常過濾器,具體取決於最適合您的要求的方式。
為了普遍套用全域異常篩選器,首先將異常篩選器合併到您的主 main.ts
檔案中。隨後,向 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();
為了將異常與控制器關聯起來,需要使用「UseFilters」裝飾器以及對應的異常過濾器。該過程涉及導入“UseFilters”裝飾器和特定的異常過濾器。隨後,必須使用「@UseFilters」裝飾器對控制器類別進行註釋,同時也將異常過濾器的實例作為參數傳遞給裝飾器。
@Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}
應用過濾器的位置將決定其錯誤處理能力的範圍。如果過濾器綁定到特定控制器,則它將僅適用於該特定控制器,而應用程式範圍的過濾器將涵蓋整個應用程式。
使用內建異常拋出錯誤
Nest.js 提供了一系列可用於引發錯誤的預定義異常類別,這些類別旨在透過提供以有組織的方式管理異常的標準化方法來簡化錯誤處理和簡化應用程式開發。
事實上,我們可以利用「NotFoundException」類別來產生 404 狀態代碼錯誤,以回應伺服器無法滿足的請求。當嘗試存取伺服器上不存在的資源或頁面時,通常會使用此異常。透過拋出此異常,伺服器可以向客戶端指示請求的內容不可用,並提供有關請求失敗原因的資訊。
getUserById(id: number) {
const user = users.find((user) => user.id === id);
if (!user) {
throw new NotFoundException({
message: `User with id ${id} not found`,
});
}
}
上述程式碼段透過條件表達式來驗證指定使用者是否存在。如果不存在,它會利用 NotFoundException 類別並提供相應的訊息作為參數來引發 404 異常。
常見的內建異常類
其他預先定義的異常類別包括但不限於以下範例。
BadRequestException 是軟體開發中的特殊異常,表示狀態代碼為 400 的 HTTP 回應。當客戶端的請求被伺服器視為無效或格式不正確而導致無法處理時,就會拋出此異常。此例外的主要含義是客戶必須相應地調整其請求以糾正任何錯誤或違規行為。
UnauthorizedException 類別拋出一個異常,表示未經授權的訪問,並附帶 HTTP 狀態代碼 401。在用戶未經身份驗證或不具備訪問特定資源所需的權限的情況下,可能會拋出此異常。 。
ForbiddenException
類別表示一個異常,表示未經授權的訪問,並帶有 HTTP 狀態代碼 403。在使用者已成功通過身份驗證但缺乏執行特定操作所需的權限的情況下可能會引發此異常。
RequestTimeoutException
是一個基於 Java 的異常,當請求超出其指定的時間限制時拋出,導致 HTTP 狀態代碼為 408。伺服器可以使用此異常來終止處理時間比預期時間長的請求。
ConflictException
類別表示由於 409 狀態碼衝突而發生的異常。當客戶端的請求與正在操作的資源的當前狀態衝突時,例如在嘗試操作時,可能會拋出此類異常。建立一個已經建立的資源。
InternalServerErrorException
是一種異常類型,表示伺服器端基礎架構內發生不可預見的錯誤,導致無法滿足要求的任務。這個特殊的異常有一個關聯的 HTTP 狀態碼 500,只要伺服器端出現意外問題,導致無法滿足客戶端的需求,就應該使用該異常。
Nest.js 中錯誤處理的最佳實踐
為了有效管理 Nest.js 應用程式中的錯誤,使用捕獲全域異常或特定於各個控制器的異常過濾器非常重要。另外,可以建立針對特定錯誤類型的客製化異常過濾器。
此外,利用合適的內建異常類別來拋出準確且重要的錯誤訊息至關重要。這種方法大大有助於增強 Nest.js 應用程式的可靠性。