NestJS ships a full set of HttpException subclasses matching common HTTP status codes. This lesson covers when to use each one and how to customize their response body.
The Base HttpException Class
Every built-in exception extends HttpException, which takes a response body (a string or object) and a status code. Throwing any subclass anywhere in your request pipeline, controller, service, guard, pipe, is automatically caught and formatted by Nest's exception layer.
import { NotFoundException } from '@nestjs/common';
throw new NotFoundException('Cat not found');
// equivalent to:
throw new HttpException('Cat not found', 404);
NotFoundException is simply a convenience subclass that hardcodes status 404, both lines above produce an identical response.
Common Built-in Exception Classes
new BadRequestException() // 400
new UnauthorizedException() // 401
new ForbiddenException() // 403
new NotFoundException() // 404
new ConflictException() // 409
new UnprocessableEntityException() // 422
new InternalServerErrorException() // 500
Each subclass hardcodes the matching HTTP status code so you don't repeat numeric literals.
The constructor accepts a string message or a custom object for the response body.
Throwing from a service is just as valid as throwing from a controller, the exception layer catches both equally.
Prefer the most specific exception available rather than a generic HttpException with a manual status code.
HTTP Exception Reference
The built-in exception classes and when to use them.
Class
Status
Typical Use
BadRequestException
400
Malformed or invalid input
UnauthorizedException
401
Missing or invalid authentication
ForbiddenException
403
Authenticated but not permitted
NotFoundException
404
Resource does not exist
ConflictException
409
Duplicate or conflicting resource
UnprocessableEntityException
422
Semantically invalid input
InternalServerErrorException
500
Unexpected server-side failure
Customizing the Response Body
Passing an object instead of a string to any HttpException subclass lets you control the exact response shape, useful for adding an error code alongside a human-readable message.
throw new BadRequestException({
errorCode: 'INVALID_EMAIL',
message: 'The provided email address is not valid',
});
Choosing the Right Status Code
Picking an accurate status code matters for API consumers building automated retry or error-handling logic. 400 generally means the client sent something malformed; 422 means the request was well-formed but semantically invalid (like a business rule violation); 409 specifically signals a conflicting state.
Common Mistakes
Throwing a generic HttpException with a hardcoded status number instead of the matching named subclass.
Returning 404 for authorization failures that should really be 403 (or vice versa).
Using 400 for every kind of validation failure instead of distinguishing malformed input from semantic violations.
Including sensitive internal details in a custom response body meant for public API consumers.
Key Takeaways
Built-in exception subclasses hardcode their matching HTTP status code for convenience and clarity.
Exceptions can be thrown from controllers, services, guards, or pipes, all are caught the same way.
Passing an object instead of a string customizes the full response body.
Choosing the most accurate status code improves how well clients can handle errors programmatically.
Pro Tip
Standardize on a small, documented set of custom error codes (like INVALID_EMAIL, RESOURCE_LOCKED) passed inside your exception response bodies, giving API consumers something more precise and stable to branch on than parsing your human-readable message text.
You now know the built-in HTTP exception classes. Next, learn how to build Custom Exceptions for domain-specific error cases.