blog.dopana

Back

Error handling quyết định reliability của ứng dụng. Code không xử lý lỗi đúng cách là code không sẵn sàng cho production.

Error Types#

// 1. Operational Error — lỗi có thể dự đoán
//    - Validation fails
//    - Network timeout
//    - Rate limit exceeded
//    → Nên handle graceful

// 2. Programmer Error — bug
//    - TypeError, ReferenceError
//    - Logic sai
//    → Nên crash hoặc restart

// 3. System Error — lỗi infrastructure
//    - DB connection lost
//    - Disk full
//    → Nên retry hoặc failover
typescript

Custom Error Hierarchy#

Result Pattern — Không Try/Catch Tràn Lan#

Express Error Handler#

Retry Pattern#

Circuit Breaker#

Graceful Degradation#

Khi service phụ thuộc fail — app vẫn hoạt động (có thể giảm chức năng):

async function getUserProfile(userId: number) {
  const user = await db.user.findUnique({ where: { id: userId } });
  if (!user) throw new NotFoundError('User', userId);

  // Recommendations là không critical
  let recommendations: Recommendation[] = [];
  try {
    recommendations = await recommendationService.get(userId);
  } catch (err) {
    logger.warn({ err }, 'Recommendation service unavailable');
    // Degrade gracefully — empty recommendations
  }

  return { ...user, recommendations };
}
typescript

Logging Errors#

// Cấu trúc log chuẩn
logger.error({
  err,                      // Error object
  requestId: req.id,
  userId: req.user?.id,
  path: req.path,
  method: req.method,
  duration: Date.now() - start,
  // Không log: password, token, secret
});
typescript

Monitoring — Error Tracking#

Checklist#

  • Custom error classes (AppError → NotFoundError, ValidationError…)
  • Global error handler (không try/catch mỗi route)
  • Retry với exponential backoff + jitter
  • Circuit breaker cho external dependencies
  • Graceful degradation khi service phụ fail
  • Structured error log (không console.error)
  • Error tracking (Sentry, Datadog)
  • Không leak internal error detail ra response

Kết Luận#

Error handling là tính năng — không phì phụ. Result pattern cho type safety. Custom errors cho dễ debug. Retry + circuit breaker cho resilience. Graceful degradation cho user experience. Đầu tư vào error handling ngay từ đầu — không phải sau khi production crash.

Tài liệu tham khảo#