Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
40 prioritized NestJS best practices across architecture, DI, security, performance, testing, and microservices.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/error-handle-async-errors.md
1---2title: Handle Async Errors Properly3impact: HIGH4impactDescription: Prevents process crashes from unhandled rejections5tags: error-handling, async, promises6---78## Handle Async Errors Properly910NestJS automatically catches errors from async route handlers, but errors from background tasks, event handlers, and manually created promises can crash your application. Always handle async errors explicitly and use global handlers as a safety net.1112**Incorrect (fire-and-forget without error handling):**1314```typescript15// Fire-and-forget without error handling16@Injectable()17export class UsersService {18async createUser(dto: CreateUserDto): Promise<User> {19const user = await this.repo.save(dto);2021// Fire and forget - if this fails, error is unhandled!22this.emailService.sendWelcome(user.email);2324return user;25}26}2728// Unhandled promise in event handler29@Injectable()30export class OrdersService {31@OnEvent('order.created')32handleOrderCreated(event: OrderCreatedEvent) {33// This returns a promise but it's not awaited!34this.processOrder(event);35// Errors will crash the process36}3738private async processOrder(event: OrderCreatedEvent): Promise<void> {39await this.inventoryService.reserve(event.items);40await this.notificationService.send(event.userId);41}42}4344// Missing try-catch in scheduled tasks45@Cron('0 0 * * *')46async dailyCleanup(): Promise<void> {47await this.cleanupService.run();48// If this throws, no error handling49}50```5152**Correct (explicit async error handling):**5354```typescript55// Handle fire-and-forget with explicit catch56@Injectable()57export class UsersService {58private readonly logger = new Logger(UsersService.name);5960async createUser(dto: CreateUserDto): Promise<User> {61const user = await this.repo.save(dto);6263// Explicitly catch and log errors64this.emailService.sendWelcome(user.email).catch((error) => {65this.logger.error('Failed to send welcome email', error.stack);66// Optionally queue for retry67});6869return user;70}71}7273// Properly handle async event handlers74@Injectable()75export class OrdersService {76private readonly logger = new Logger(OrdersService.name);7778@OnEvent('order.created')79async handleOrderCreated(event: OrderCreatedEvent): Promise<void> {80try {81await this.processOrder(event);82} catch (error) {83this.logger.error('Failed to process order', { event, error });84// Don't rethrow - would crash the process85await this.deadLetterQueue.add('order.created', event);86}87}88}8990// Safe scheduled tasks91@Injectable()92export class CleanupService {93private readonly logger = new Logger(CleanupService.name);9495@Cron('0 0 * * *')96async dailyCleanup(): Promise<void> {97try {98await this.cleanupService.run();99this.logger.log('Daily cleanup completed');100} catch (error) {101this.logger.error('Daily cleanup failed', error.stack);102// Alert or retry logic103}104}105}106107// Global unhandled rejection handler in main.ts108async function bootstrap() {109const app = await NestFactory.create(AppModule);110const logger = new Logger('Bootstrap');111112process.on('unhandledRejection', (reason, promise) => {113logger.error('Unhandled Rejection at:', promise, 'reason:', reason);114});115116process.on('uncaughtException', (error) => {117logger.error('Uncaught Exception:', error);118process.exit(1);119});120121await app.listen(3000);122}123```124125Reference: [Node.js Unhandled Rejections](https://nodejs.org/api/process.html#event-unhandledrejection)126