我同時使用例外過濾器、攔截器和驗證管道。所有這些都按預期自行作業。我在全域范圍內設定這些,因為這就是我此時所需要的。豐富了 NestJS的AllExceptionsFilter默認例外,包括 URL、Http 方法等。AddProgramVersionToResponseHeaderInterceptor用于向回應添加自定義標頭,其中包含我的應用程式和版本。用于在AppGlobalValidationPipeOptions驗證錯誤時將 Http 狀態代碼從 400 轉換為 422 Unprocessable Entity。
main.ts
...
const AppHttpAdapter = app.get(HttpAdapterHost);
app.useGlobalFilters(new AllExceptionsFilter(AppHttpAdapter));
app.useGlobalInterceptors(new AddProgramVersionToResponseHeaderInterceptor());
app.useGlobalPipes(new ValidationPipe(AppGlobalValidationPipeOptions));
await app.listen(IpPort);
所有這些都可以正常作業,直到我在代碼中遇到例外,例如路徑錯誤。
GET /doesnotexist將回傳豐富的 404 結果,它具有我想要的內容,但是 AddProgramVersionToResponseHeaderInterceptor 中的 Http Header 欄位不會更新標頭。
我已經以不同的順序定義了全域設定,以查看是否允許攔截器添加 Http 標頭,但這不起作用。
AddProgramVersionToResponseHeaderInterceptor
export class AddProgramVersionToResponseHeaderInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const AppInfo: ApplicationInformationService = new ApplicationInformationService();
const EmulatorInfo: string = `${AppInfo.Name}/${AppInfo.Version}`;
const ResponseObj: ExpressResponse = context.switchToHttp().getResponse();
ResponseObj.setHeader('my-custom-header', EmulatorInfo);
return next.handle().pipe();
}
}
所有例外過濾器
export class AllExceptionsFilter implements ExceptionFilter {
constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
catch(exception: unknown, host: ArgumentsHost): void {
// In certain situations `httpAdapter` might not be available in the
// constructor method, thus we should resolve it here.
const { httpAdapter } = this.httpAdapterHost;
const ctx = host.switchToHttp();
const HttpStatusCode: number = exception instanceof HttpException ? exception.getStatus() : HttpStatus.EXPECTATION_FAILED;
const RequestData: string = httpAdapter.getRequestUrl(ctx.getRequest());
const RequestURLInfo: string[] = RequestData.split('?');
const ResponseBody: IBackendException = {
Hostname: httpAdapter.getRequestHostname(ctx.getRequest()),
Message: exception instanceof HttpException ? (exception.getResponse() as INestHttpException).message : [(exception as Error).message.toString()],
Method: httpAdapter.getRequestMethod(ctx.getRequest()),
StackTrace: exception instanceof HttpException ? '' : (exception as Error).stack,
StatusCode: HttpStatusCode,
Timestamp: new Date().toISOString(),
URL: RequestURLInfo[0],
Parameters: RequestURLInfo[1],
};
httpAdapter.reply(ctx.getResponse(), ResponseBody, HttpStatusCode);
};
AppGlobalValidationPipeOptions
export const AppGlobalValidationPipeOptions: ValidationPipeOptions = {
errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
transform: true,
whitelist: true,
};
uj5u.com熱心網友回復:
攔截器系結到使用 HTTP 動詞裝飾器標記的路由處理程式(類方法)。如果沒有路由處理程式(如 404),則無法呼叫攔截器。我的OgmaInterceptor也有同樣的問題。您可以創建一個@All('*')拋出 a 的處理程式,也NotFoundException可以像現在一樣在過濾器中處理它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/462055.html
