arshid dar
arshid dar

Reputation: 1485

how to send error codes in nestjs app from controller?

How can i send error codes in nestjs apart from 200? i tried to inject response object in a method but there is no method to send error.

save(@Body() body: any, @Res() response: Response): string {
    console.log("posting...")
    console.log(body)
    return "saving " + JSON.stringify(body)
}

the above code send body with 20X status i want to send different status code like 400 or 500.

Upvotes: 35

Views: 99905

Answers (6)

Dmitriy Mozgovoy
Dmitriy Mozgovoy

Reputation: 1597

I just checked in Postman and it seems this works, although it looks like a hack:

import { Post, Res, HttpStatus, Controller } from '@nestjs/common';
import { Response } from 'express';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(@Res({ passthrough: true }) res: Response): string {
    res.status(203);
    return this.appService.getHello();
  }
}

Notice that the Response::status from @nests/common is a readonly and non-callable. That is why we have to use Response from express

Upvotes: 5

Amadeusz Blanik
Amadeusz Blanik

Reputation: 768

You should use exception filters in your case instead.

In your case you'll need:

throw new BadRequestException(error);

Or you can use

throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);

That will return

{
  "statusCode": 403,
  "message": "Forbidden"
}

Docs: https://docs.nestjs.com/exception-filters

Upvotes: 68

Leo Moore
Leo Moore

Reputation: 2158

To return a status code in nestjs, you need to include the @Res() in your parameters. Normally in nestjs the passthrough option on the Response object is set to false by default. This means anything you do will not passthrough into the Response object.

You don't need to return the response object as if you do you will get an error like this because it will try to replace your custom response with the standard nestjs response.

Cannot set headers after they are sent to the client

Also, the status should be set before you send the response or it will default to a status code of 200.

async myfunction(@Param('id') id: string, @Res({passthrough: true}) response: Response) {

   //do stuff ....

   response.status(HttpStatus.FORBIDDEN).send('You are not allowed to do that');
   return;
}

Upvotes: 4

Klesun
Klesun

Reputation: 13673

So the complete example of returning http status code without neither throwing errors, nor via static @HttpCode():

import { Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';
...
  @Post()
  save(@Res() response: Response) {
    response
      .status(HttpStatus.BAD_REQUEST)
      .send("saving " + JSON.stringify(body));
  }

You need to get use of the @Res() decorator to get hold of the underlying express Response object and use it's status() method.

Though I still wonder if there is some other way not involving operating stateful objects and just making a clean return in nestjs like you would do in spring...

Upvotes: 22

Madan Murari
Madan Murari

Reputation: 179

Whatever code you will write it will appear in your response

@HttpCode(204)
create() {
  return 'This action adds a new cat';
}

Upvotes: 13

Jay McDoniel
Jay McDoniel

Reputation: 70171

You could always throw an Error and let Nest handle the error code for you. The documentation has a great bit on what errors are already defined and they are common HTTP errors so they follow the expected codes. Or you could throw your own errors, following the syntax in the docs

Upvotes: 2

Related Questions