このコントローラーをNestJSプロジェクトに入れましょう:
_ @Post('resetpassword')
@HttpCode(200)
async requestPasswordReset(
@Body() body: RequestPasswordResetDTO,
): Promise<boolean> {
try {
return await this.authService.requestPasswordReset(body);
} catch (e) {
if (e instanceof EntityNotFoundError) {
// Throw same exception format as class-validator throwing (ValidationError)
} else throw e;
}
}
_
DTOの定義:
_export class RequestPasswordResetDTO {
@IsNotEmpty()
@IsEmail()
public email!: string;
}
_
this.authService.requestPasswordReset(body);
がValidationError
例外をスローしたときに、EntityNotFoundError
形式(プロパティ、値、制約など)でエラーをスローします。
このエラーを手動で作成するにはどうすればよいですか?これらのエラーは、_class-validator
_によるDTO検証が失敗したときにスローされます。また、これらは非同期のデータベース検証ではなく、単なる静的検証でもかまいません。
したがって、最終的なAPI応答形式は、たとえば次のようになります。
_{
"statusCode": 400,
"error": "Bad Request",
"message": [
{
"target": {
"email": "[email protected]"
},
"value": "[email protected]",
"property": "email",
"children": [],
"constraints": {
"exists": "email address does not exists"
}
}
]
}
_
一貫したエラー処理が必要です:)
Exception Filter を使用して、その例外に対するカスタマイズされた応答を作成できます。最初に、例外フィルターを定義します。
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
// import { EntityNotFoundError } from 'wherever';
@Catch(EntityNotFoundError)
export class EntityNotFoundExceptionFilter implements ExceptionFilter {
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": 400,
"error": "Bad Request",
"message": [
{
"target": {},
"property": "email",
"children": [],
"constraints": {
"isEmail": "email must be an email"
}
},
// other field exceptions
]
});
}
}
次に、コントローラーに戻って、フィルターを使用します。
// ...
import { EntityNotFoundExceptionFilter } from 'its module';
// ...
@Post('resetpassword')
@HttpCode(200)
@UseFilters(EntityNotFoundExceptionFilter)
async requestPasswordReset(
@Body() body: RequestPasswordResetDTO
): Promise<boolean> {
return await this.authService.requestPasswordReset(body);
}
これは問題なく動作するはずです。
アプリにValidationPipe
を追加するときは、カスタムexceptionFactory
を指定します。
app.useGlobalPipes(
new ValidationPipe({
exceptionFactory: (validationErrors: ValidationError[] = []) => {
return new BadRequestException(validationErrors);
},
})
);
これで、意図した結果が得られます。
比較のために、元のNestJSバージョン here を確認できます。