ExceptionFilter
を使用して、例外をHTTP Counterpartにマッピングしようとします。
これは私のコードです:
@Catch(EntityNotFoundError)
export class EntityNotFoundFilter implements ExceptionFilter {
catch(exception: EntityNotFoundError, _Host: ArgumentsHost) {
throw new NotFoundException(exception.message);
}
}
_
しかし、フィルタコードが実行されると、UnhandledPromiseRejectionWarning
(node:3065) UnhandledPromiseRejectionWarning: Error: [object Object]
at EntityNotFoundFilter.catch ([...]/errors.ts:32:15)
at ExceptionsHandler.invokeCustomFilters ([...]/node_modules/@nestjs/core/exceptions/exceptions-handler.js:49:26)
at ExceptionsHandler.next ([...]/node_modules/@nestjs/core/exceptions/exceptions-handler.js:13:18)
at [...]/node_modules/@nestjs/core/router/router-proxy.js:12:35
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:182:7)
(node:3065) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 5)
_
どうすればいいですか?
ExceptionFilter
応答が送信される前に呼び出される最後の場所は常に最後の場所です、それは応答を作成する責任があります。 ExceptionFilter
内の例外をrethroutすることはできません。
@Catch(EntityNotFoundError)
export class EntityNotFoundFilter implements ExceptionFilter {
catch(exception: EntityNotFoundError, Host: ArgumentsHost) {
const response = Host.switchToHttp().getResponse();
response.status(404).json({ message: exception.message });
}
}
_
あるいは、 Interceptor
エラーを変換することができます。
@Injectable()
export class NotFoundInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
// next.handle() is an Observable of the controller's result value
return next.handle()
.pipe(catchError(error => {
if (error instanceof EntityNotFoundError) {
throw new NotFoundException(error.message);
} else {
throw error;
}
}));
}
}
_
この中で試してみてください codesandbox 。
Kim Kern Solutionに基づくこの抽象クラスを作成しました
export abstract class AbstractErrorInterceptor<T> implements NestInterceptor {
protected interceptedType: new (...args) => T;
intercept(
context: ExecutionContext,
call$: Observable<any>,
): Observable<any> | Promise<Observable<any>> {
return call$.pipe(
catchError(exception => {
if (exception instanceof this.interceptedType) {
this.handleError(exception);
}
throw exception;
}),
);
}
abstract handleError(exception: T);
}
_
そしていくつかの実装
export class EntityNotFoundFilter extends AbstractErrorInterceptor<EntityNotFoundError> {
interceptedType = EntityNotFoundError;
handleError(exception: EntityNotFoundError) {
throw new NotFoundException(exception.message);
}
}
_
NESTJSに既に出荷している独自のバージョンのHTTPベースの例外クラスを作成しているのは奇妙なようです。デフォルトでは、これらは正しいエラーコードを使用して自動的にHTTP応答に変換されます。代わりに、インターセプターと抽象クラスの実装でオーバーヘッドを追加しています。これはあなたが参照していた組み込みメカニズムです。
throw new BadRequestException('you done goofed');
結果が得られます。
{"statusCode":400,"error":"Bad Request","message":"you done goofed"}
_