如何修改nestjs graphql异常过滤器中的HTTPException消息?

Md.*_*man 11 graphql nestjs nestjs-i18n

我想在class-validatorNestjs graphql 的错误消息中使用本地化。但我无法设置翻译后的消息作为响应并将其返回。我尝试了很多解决方案,例如response.status(400).json({....})发送修改后的响应,但这没有用,

我用过了,

 providers: [
{
  provide: APP_FILTER,
  useClass: AllExceptionFilter,
},
Run Code Online (Sandbox Code Playgroud)

],

我的AllExceptionFilter.ts

import { Catch, ArgumentsHost, BadRequestException } from '@nestjs/common';
import { GqlExceptionFilter, GqlArgumentsHost } from '@nestjs/graphql';
import { I18nService } from 'nestjs-i18n';

@Catch(BadRequestException)
export class AllExceptionFilter implements GqlExceptionFilter {
  constructor(private readonly i18n: I18nService) {}

  async catch(exception: BadRequestException, host: ArgumentsHost) {
   const gqlHost = GqlArgumentsHost.create(host);

    const translatedMessage = await this.i18n.translate('validation.NotEmpty', {
       lang: 'en',
      });


     // In this place I want the modifications and then return the newexception object.

     return exception;
  }
}
Run Code Online (Sandbox Code Playgroud)

我想用翻译后的消息修改异常消息。

就像这样的结果console.log(exception.getResponse());

    {
      statusCode: 400,
      message: [
        'password must be longer than or equal to 8 characters',
        'Both "passwordConfirm" and "password" fields are not Matched!'
      ],
      error: 'Bad Request'
    }
Run Code Online (Sandbox Code Playgroud)

但我希望消息数组消息带有翻译后的消息,就像我需要一个像exception.setResponse({message:['Translated Message', 'Translated Message2']}). 或者类似我将构造一个对象然后重新创建这个异常对象。

然后的最终输出console.log(exception.getResponse()); 将是这样的

   {
      statusCode: 400,
      message: [
        'Translated Message',
        'Translated Message 2'
      ],
      error: 'Bad Request'
    }
Run Code Online (Sandbox Code Playgroud)

我返回的异常对象将包含在这个翻译后的消息中。

这个怎么做?或者有没有更好的方法使用nestjs-i18nextgraphql 的本地化来翻译class-validator错误消息或 HTTPException 错误消息?

tou*_*uri 0

正如 Nestjs-i18n 的主要文档提到的:

如果您想要不同的输出,请创建您自己的拦截器!有关示例,请查看I18nValidationExceptionFilter

您可以自定义并返回自己的异常,如下所示:

@Catch(I18nValidationException)
export class I18nValidationExceptionFilter implements ExceptionFilter {
    constructor(
        private readonly options: I18nValidationExceptionFilterOptions = {
            detailedErrors: true,
        },
    ) {}
    catch(exception: I18nValidationException, host: ArgumentsHost) {
        const i18n = I18nContext.current();

        const errors = formatI18nErrors(exception.errors ?? [], i18n.service, {
            lang: i18n.lang,
        });

        switch (host.getType() as string) {
            case 'http':
                const response = host.switchToHttp().getResponse();
                response
                    .status(
                        this.options.errorHttpStatusCode ||
                            exception.getStatus(),
                    )
                    .send({
                        statusCode:
                            this.options.errorHttpStatusCode ||
                            exception.getStatus(),
                        message: exception.getResponse(),
                        errors: this.normalizeValidationErrors(errors),
                    });
                break;
            case 'graphql':
                const normalizedErrors = this.normalizeValidationErrors(errors);
                // return new exception here
                return new BadRequestException(normalizedErrors[0]);
        }
    }
...
Run Code Online (Sandbox Code Playgroud)

另外,请确保将detailedErrors值设置为false

app.useGlobalFilters(
        new I18nValidationExceptionFilter({
            detailedErrors: false,
        }),
    );
Run Code Online (Sandbox Code Playgroud)

在我的示例代码中,我返回了第一条错误消息。如果你想返回整个对象,也许你需要在返回之前对其进行字符串化。