Built-in HTTP Exceptions

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 6 min

NestJS provides a comprehensive set of built-in exception classes extending HttpException, covering almost every standard HTTP error scenario.

Overview

Instead of manually throwing new HttpException('Not Found', HttpStatus.NOT_FOUND), NestJS gives you a suite of helper classes. These make your code cleaner, more readable, and guarantee that standard HTTP status codes are used correctly.

When you throw one of these, the default global exception filter automatically formats it into a standard JSON response containing a statusCode, message, and error description.

Key Concepts

  • Common Exceptions: BadRequestException (400), UnauthorizedException (401), ForbiddenException (403), NotFoundException (404), ConflictException (409).
  • Automatic Formatting: By default, new NotFoundException() generates { "statusCode": 404, "message": "Not Found" }.
  • Customizable: You can override the default message or provide a custom object payload just like you can with the base HttpException.

Code Examples

Basic Usage

The most common way to use built-in exceptions.

import { 
  Controller, 
  Get, 
  Param, 
  NotFoundException, 
  UnauthorizedException 
} from '@nestjs/common';

@Controller('users')
export class UsersController {
  
  @Get(':id')
  findOne(@Param('id') id: string) {
    if (!isValidId(id)) {
      // Sends a 401
      throw new UnauthorizedException('You must be logged in to view users');
    }

    const user = findUserInDb(id);
    
    if (!user) {
      // Sends a 404
      throw new NotFoundException(`User with ID ${id} could not be found`);
    }
    
    return user;
  }
}

Advanced Usage (Custom Error Description)

If you need to provide a custom message but also want to keep the standard HTTP error name, you can pass a second argument (the error description).

import { BadRequestException } from '@nestjs/common';

@Post()
create() {
  // Sometimes, validation libraries or external APIs return arrays of errors.
  const validationErrors = ['Password too short', 'Email invalid'];

  throw new BadRequestException(
    validationErrors,      // The custom message/data
    'Validation Failed'    // Overrides the default "Bad Request" error description
  );
}

Resulting JSON:

{
  "statusCode": 400,
  "message": [
    "Password too short",
    "Email invalid"
  ],
  "error": "Validation Failed"
}

Best Practices

  • Know the Difference: Understand the semantic difference between 401 Unauthorized (You haven’t proven who you are yet - e.g., missing JWT) and 403 Forbidden (I know who you are, but you aren’t an admin, so you can’t do this). Use the correct built-in exception for each scenario.
  • Use for Validation: The BadRequestException (400) is the standard exception thrown by the ValidationPipe when DTO validation fails. If you are doing manual validation in your controller, you should also throw this exception to keep your API responses consistent.