Structure exception handling patterns

Implement consistent exception handling using framework-provided mechanisms rather than ad-hoc try-catch blocks or manual error propagation. Use appropriate exception classes and interceptors to handle errors at the right architectural level.

copy reviewer prompt

Prompt

Reviewer Prompt

Implement consistent exception handling using framework-provided mechanisms rather than ad-hoc try-catch blocks or manual error propagation. Use appropriate exception classes and interceptors to handle errors at the right architectural level.

Key guidelines:

  1. Use built-in exception classes with proper status codes
  2. Leverage exception interceptors for cross-cutting error handling
  3. Avoid mixing different error handling approaches

Example - INCORRECT approach:

@Controller('cats')
export class CatsController {
  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    try {
      await this.catsService.create(createCatDto);
    } catch(error) {
      console.error(error);
      return []; // Swallowing error, returning empty result
    }
  }
}

CORRECT approach:

@Controller('cats')
export class CatsController {
  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    // Let exception filter handle errors
    return await this.catsService.create(createCatDto);
  }
}

// In a custom exception filter
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    // Proper error handling with status codes and logging
    const status = exception instanceof HttpException 
      ? exception.getStatus()
      : HttpStatus.INTERNAL_SERVER_ERROR;
    // Handle error appropriately...
  }
}

Source discussions