nestjstypescriptbackend
typed-result vs HttpException in NestJS
2 min read
In NestJS, exceptions are usually thrown in the service or controller layer and handled globally by an exception filter.
Repositories typically return:
- entity
null- database error
instead of throwing HTTP exceptions directly.
Because of that, comparing typed-result and HttpException is more about error flow design than where exceptions are caught.
Using HttpException
A common NestJS approach:
@Injectable()
export class UserService {
async findUser(id: string) {
const user = await this.userRepository.findById(id);
if (!user) {
throw new NotFoundException('User not found');
}
return user;
}
}
The exception is later transformed into an HTTP response by NestJS exception filters.
Pros
- Simple
- Native NestJS style
- Less boilerplate
Cons
- Business logic depends on HTTP exceptions
- Harder to reuse outside REST APIs
Using typed-result
Instead of throwing, services return explicit results.
async findUser(id: string): Promise<Result<User, 'NOT_FOUND'>> {
const user = await this.userRepository.findById(id);
if (!user) {
return Err('NOT_FOUND');
}
return Ok(user);
}
Controller layer maps domain errors to HTTP exceptions.
const result = await this.userService.findUser(id);
if (result.isErr) {
throw new NotFoundException();
}
return result.value;
Main Difference
HttpException | typed-result |
|---|---|
| Exception-based flow | Result-based flow |
| Implicit error handling | Explicit error handling |
| Coupled to NestJS HTTP layer | Framework-independent |
| Less code | More type safety |
Which One Should You Use?
Use HttpException
When building:
- CRUD APIs
- small services
- simple applications
Use typed-result
When building:
- complex business logic
- clean architecture
- reusable domain services
- multi-transport systems
Best Practice
A practical approach is:
- Repository → return entity or
null - Service → business validation
- Controller → map to HTTP response
For many projects:
- simple flows →
HttpException - complex domain logic →
typed-result
Both approaches are valid depending on architecture complexity.