Search code examples
javascriptnode.jstypescriptnestjs

How to make custom response using globalPipse in nestjs


I wrote an api in user.controller using dto of 'class-validator'.

  @Post('/')
  public async createUser(
    @Res() res,
    @Body() createUserDto: CreateUserDto,
  ) {
    ... do something
  }

And I put useGlobalPipes in main.ts.

  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      transform: true,
      forbidNonWhitelisted: true,
      transformOptions: {
        enableImplicitConversion: true,
      },
    }),
  );

When I request to the api, I get a response below.

{
    "statusCode": 400,
    "message": [
        "userName should not be empty",
        "userName must be a string",
    ],
    "error": "Bad Request"
}

So far, it works without problem with nestjs.
But I want to get a custom response like this.

{
    "code": 400,
    "errorReason": [
        "userName should not be empty",
        "userName must be a string",
    ],
    "msg": "Bad Request",
    "success": false
}

Can I get this custom response maintaining the code above?
If it can do it, could you give me some advice or some code for this?
Thank you for reading my question.


Solution

  • In Nest, pipes are good for validation, transforming an incoming object, maybe talking to a database in some circumstances, and throwing errors if anything goes wrong. If you want to change the response, after an error is thrown, you'll need to look into using an ExceptionFilter Where you can do something like

    @Catch()
    export class CatchAllFilter implements ExceptionFilter {
    
      catch(exception: Error, host: ArgumentHost) {
        res
          .status((exception.getStatus && exception.getStatus()) || 500)
          .send({
            (exception.getResponse && ...exception.getResponse()) || ...{ message: exception.message },
            success: false
          });
      }
    }
    

    You're bound to get type errors with the above code, but it should lead you on the right track