JavaScript 中的错误处理:try/catch、async/await 和高级模式

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript 中的高级错误处理:从 try/catch 到全局拦截器

\n\n

错误处理不仅仅是“用 try/catch 包裹代码”。在真实的 Node.js 生产应用中,妥善的异常管理可以避免服务器崩溃、正确记录问题并向用户提供清晰的信息。在本文中,我们将探讨 JavaScript 中超越基本语法的高级错误处理技术。

\n\n

1. 深入理解 try/catch 和 finally

\n\n

经典的 try...catch...finally 结构仍然是同步处理的基础。然而,在高级层面,理解其工作细节至关重要。

\n\n
function riskyOperation(value) {\n  if (typeof value !== 'number') {\n    throw new TypeError('Argument must be a number');\n  }\n  if (value < 0) {\n    throw new RangeError('Value cannot be negative');\n  }\n  return Math.sqrt(value);\n}\n\ntry {\n  const result = riskyOperation(-4);\n  console.log('Result:', result);\n} catch (error) {\n  if (error instanceof TypeError) {\n    console.error('Type Error:', error.message);\n  } else if (error instanceof RangeError) {\n    console.error('Range Error:', error.message);\n  } else {\n    console.error('Unknown error:', error);\n  }\n} finally {\n  console.log('Cleanup: always executed');\n}
\n\n

关键点:

\n
    \n
  • finally 块始终执行,即使 try 或 catch 中有 return。
  • \n
  • 使用内置错误类(TypeError、RangeError、SyntaxError)进行精确识别。
  • \n
  • 不要捕获你无法处理的错误——让它们向上冒泡。
  • \n
\n\n

2. 自定义错误类和扩展 Error

\n\n

对于大型项目,标准错误类型是不够的。创建自己的类可以添加元数据(HTTP 状态码、错误代码、上下文)并简化过滤。

\n\n
class AppError extends Error {\n  constructor(message, statusCode, code) {\n    super(message);\n    this.name = 'AppError';\n    this.statusCode = statusCode;\n    this.code = code;\n    Error.captureStackTrace(this, this.constructor);\n  }\n}\n\nclass ValidationError extends AppError {\n  constructor(message, field) {\n    super(message, 400, 'VALIDATION_ERROR');\n    this.field = field;\n  }\n}\n\nclass DatabaseError extends AppError {\n  constructor(message, query) {\n    super(message, 500, 'DB_ERROR');\n    this.query = query;\n  }\n}\n\n// 使用\ntry {\n  throw new ValidationError('Email is required', 'email');\n} catch (error) {\n  if (error instanceof ValidationError) {\n    console.log(`Field: ${error.field}, Status: ${error.statusCode}`);\n  }\n}
\n\n

为什么这很重要:自定义错误允许集中处理不同场景(例如,在 Express.js 中间件中)并向客户端返回结构化的 JSON。

\n\n

3. 异步代码中的错误处理:async/await 和 Promise

\n\n

在 Node.js 中,大部分代码是异步的。Promise 和 async/await 中的错误需要特殊处理。

\n\n

3.1. Promise 处理

\n\n
function fetchUserData(userId) {\n  return new Promise((resolve, reject) => {\n    if (userId <= 0) {\n      reject(new RangeError('Invalid user ID'));\n    }\n    // 模拟数据库请求\n    setTimeout(() => resolve({ id: userId, name: 'Alice' }), 100);\n  });\n}\n\nfetchUserData(-1)\n  .then(user => console.log(user))\n  .catch(error => {\n    console.error('Promise rejected:', error.message);\n  })\n  .finally(() => console.log('Cleanup after promise'));
\n\n

3.2. async/await 处理

\n\n
async function getUserProfile(userId) {\n  try {\n    const user = await fetchUserData(userId);\n    const posts = await fetchUserPosts(user.id                

博客

书籍推荐