Throw, don't juggle
In Express you pass errors around with res.status(…). In Nest you just throw: the built-in exception filter turns NotFoundException, ConflictException and friends into proper HTTP responses — from anywhere, even deep inside a service.
The HttpException family
import { ConflictException, Controller, Get, HttpException, HttpStatus, NotFoundException, Param } from "@nestjs/common";
@Controller("tables")
export class TablesController {
private booked = new Set(["5"]);
@Get(":n/book")
book(@Param("n") n: string) {
if (Number(n) > 20) throw new NotFoundException(`Table ${n} does not exist`);
if (this.booked.has(n)) throw new ConflictException(`Table ${n} is already booked`);
if (n === "13") throw new HttpException("We skip table 13", HttpStatus.UNPROCESSABLE_ENTITY);
this.booked.add(n);
return { booked: Number(n) };
}
@Get("boom")
boom() {
throw new Error("database is down");
}
}- Throw from services too: the controller doesn't need to catch.
- Custom exception filters (@Catch()) can reshape every error response — e.g. to add a request id.