фильтр исключений nestjs не вызывается, когда исключение создается из пользовательского канала проверки

#javascript #node.js #typescript #nestjs

Вопрос:

Я пытаюсь проверить запрос json в своем приложении nestjs, используя свой собственный класс канала проверки «SchemaValidationPipe», который создает исключение BadRequestException. Мой глобальный фильтр исключений не улавливает исключение, вызванное из канала проверки.

Если я создам исключение из класса контроллера, то глобальный фильтр исключений сможет перехватить исключение.

 @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());
 

Ответ №1:

Похоже, вы не возвращаете предоставление из validate метода, поэтому оно считается недействительным. Это означает, что обещание будет выполняться вне жизненного цикла связанного запроса и может привести к необработанному отказу в предоставлении. Вам просто нужно добавить return schemaValidator.validate...

Ответ №2:

Я могу решить проблему, сделав метод преобразования асинхронным в классе 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');
    }
  }
}