NestJSを使用してAPIを作成しているときに、エラー/例外を処理するための最良の方法はどれかと思いました。私は2つの異なるアプローチを見つけました:
throw new Error()
を用意し、コントローラーにcatch
を割り当て、適切な種類のHttpException
(BadRequestException
、ForbiddenException
などをスローします。)HttpException
をスローさせるだけです。両方のアプローチには長所と短所があります。
Error
を返すことができます。対応する種類のHttpException
を返すコントローラーからどのようにして知ることができますか?Http
関連のものを含めるのは間違っているようです。私はそれを行うための「ネストjs」方法(もしあれば)はどれですか?
この問題をどのように処理しますか?
ビジネスロジックがEntityNotFoundError
をスローし、それをNotFoundException
にマップするとします。
そのために、エラーを変換する 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;
}
}));
}
}
_
次に、コントローラのクラスまたはメソッドに@UseInterceptors(NotFoundInterceptor)
を追加することにより、それを使用できます。またはすべてのルートのグローバルインターセプターとしても。もちろん、1つのインターセプターで複数のエラーをマップすることもできます。
codesandbox で試してみてください。
HTTPインターフェースだけでなく、GraphQLまたはその他のインターフェースにもサービスをバインドしたい場合があります。したがって、コントローラーでビジネスロジックレベルの例外をサービスからHttpレベルの例外(BadRequestException、ForbiddenException)にキャストすることをお勧めします。
簡単に言うと次のようになります
import { BadRequestException, Injectable } from '@nestjs/common';
@Injectable()
export class HttpHelperService {
async transformExceptions(action: Promise<any>): Promise<any> {
try {
return await action;
} catch (error) {
if (error.name === 'QueryFailedError') {
if (/^duplicate key value violates unique constraint/.test(error.message)) {
throw new BadRequestException(error.detail);
} else if (/violates foreign key constraint/.test(error.message)) {
throw new BadRequestException(error.detail);
} else {
throw error;
}
} else {
throw error;
}
}
}
}
その後