Estoy tratando de validar la solicitud json en mi aplicación nestjs usando mi clase de tubería de validación personalizada "SchemaValidationPipe" que arroja BadRequestException. Mi filtro de excepción global no detecta la excepción lanzada desde la tubería de validación.
Si lanzo una excepción desde la clase del controlador, el filtro de excepción global puede detectar la excepción.
@Injectable() export class SchemaValidationPipe implements PipeTransform<any> { constructor(private schema: any) {} transform(value: any, metadata: ArgumentMetadata) { const schemaValidator = new JsonValidator(this.schema); schemaValidator .validate(value) .then((data) => { if (data) { const { isValid, message } = data; if(!isValid) throw new BadRequestException( { status : '500', message : 'Validation failed' } ); } return Promise.resolve(value); }) .catch((err) => { throw new BadRequestException('Validation failed'); }); } }
@Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter<HttpException> { catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse(); const request = ctx.getRequest(); const status = exception.getStatus(); response.status(status).json({ statusCode: status, timestamp: new Date().toISOString(), path: request.url, }); } }
const app = await NestFactory.create<NestExpressApplication>(AppModule); app.useGlobalFilters(new HttpExceptionFilter());
Puedo resolver el problema haciendo que el método de transformación sea asíncrono en la clase SchemaValidationPipe
@Injectable() export class SchemaValidationPipe implements PipeTransform<any> { constructor(private schema: any) {} async transform(value: any, metadata: ArgumentMetadata) { const schemaValidator = new JsonValidator(this.schema); try { const { isValid, message } = await schemaValidator.validate(value); if(!isValid) throw new BadRequestException( 'Validation failed' ); } catch (err) { throw new BadRequestException('Validation failed'); } } }
Parece que no devuelve el suministro del método de validate
, por lo que se considera nulo. Esto significa que la promesa se ejecutará fuera del ciclo de vida de la solicitud enlazada y puede terminar generando un rechazo de suministro no controlado. Solo debe agregar return schemaValidator.validate...