26

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.

Klesun
  • 12,280
  • 5
  • 59
  • 52
arshid dar
  • 1,355
  • 2
  • 15
  • 23
  • i was doing it wrong i was importing response from nestjs/common when i had to import Response object from express. – arshid dar Jul 04 '19 at 08:31

6 Answers6

48

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

Amadeusz Blanik
  • 568
  • 4
  • 7
  • 1
    This should be the correct response. – Naftali Apr 06 '22 at 02:08
  • @Naftali No it doesn't, it only works with exceptions for me. – Pedro Paulo Amorim Oct 20 '22 at 00:41
  • This is correct only if you want to change the response code on errors, but if you want to change the response code on success, it is incorrect. For instance, for a webhook that use the method POST for update and create, you maybe want to return 204 in the first case and 201 in the second one. – kato2 Mar 09 '23 at 13:54
16

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...

Klesun
  • 12,280
  • 5
  • 59
  • 52
  • 1
    For something like how things work in Spring you could make an interceptor that reads the response class and sets the status as you want. I don't really care for this approach, as Nest made the exception filter class specifically for error handling (and I'd argue that 400/500 error codes are errors) – Jay McDoniel May 05 '21 at 21:47
  • using `@Res` is drastically a bad habit in nestjs since it's not working with many features like interceptors, i strongly recommmend [this answer instead, cause this is official and standard way](https://stackoverflow.com/a/56892951/6791254) – TechDogLover OR kiaNasirzadeh Dec 20 '21 at 03:57
8

Whatever code you will write it will appear in your response

@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
Zico
  • 2,349
  • 2
  • 22
  • 25
Madan Murari
  • 99
  • 1
  • 2
3

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

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

  @Get()
  getHello(@Res({ passthrough: true }) res: Response): string {
    res.status(203);
    return this.appService.getHello();
  }
}
Dmitriy Mozgovoy
  • 1,419
  • 2
  • 8
  • 7
2

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

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • Isn't there some more straightforward way, like returning some sort of `Response` object instead of string? – Klesun May 05 '21 at 20:58
  • Why would you want to send an error status without throwing an error? Other than what I mentioned, you could just use `res.status(400).send(stringifiedBody)` – Jay McDoniel May 05 '21 at 20:59
  • Yeah, thanks, that's the answer I was looking for. Sorry for the downvote, it's just in the background I came from throwing exception is [considered](https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why) an anti-pattern. – Klesun May 05 '21 at 21:03
  • 2
    success codes like 201 created and 202 accepted are NOT errors but would ideally have the correct status codes set on the response. throwing an error for these feel really wrong – Dave Amphlett Jun 22 '22 at 16:00
  • I agree with that. I would not suggest throwing an error for setting success responses. The original question was about error codes though, where exceptions are the norm in Nest – Jay McDoniel Jun 22 '22 at 16:08
2

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;
}
Leo Moore
  • 2,118
  • 2
  • 19
  • 21