← [ BACK_TO_NOTES ]

try-catch 错误处理

说明 throw/try/catch/finally 的控制流、异步错误边界,以及何时把错误变成返回值或上报。

#howto #growing #dev #javascript

[!info] related notes

try-catch 错误处理

这个概念为什么出现

库存接口失败、JSON 解析失败、权限不足——若让异常裸奔,UI 白屏;若全部吞掉,故障不可见。try/catch 是同步(及 await)路径上的结构化错误边界。

[!abstract] 一句话理解 throw 中断正常路径;catch 捕获该执行路径中的抛出,是否可恢复由代码判断;离开 try/catch 时先执行 finally。

最小可运行示例

场景:解析导入的 SKU JSON 文件

function parseSkuJson(text) {
  try {
    const data = JSON.parse(text)
    if (!data || typeof data.sku !== 'string') {
      throw new Error('SKU 字段缺失')
    }
    return { ok: true, data }
  } catch (err) {
    return { ok: false, error: err instanceof Error ? err.message : String(err) }
  } finally {
    // 教学点:释放临时状态/打点;不要在 finally 里 return 掩盖结果
    console.log('parseSkuJson finished')
  }
}

console.log(parseSkuJson('{"sku":"A-01"}'))
console.log(parseSkuJson('{'))

异步边界

async function load() {
  try {
    const response = await fetch('/api/x')
    if (!response.ok) throw new Error(`HTTP ${response.status}`)
    return await response.json()
  } catch (e) {
    // 可在这里添加上下文;示例继续传播,避免吞掉错误。
    throw new Error('加载接口数据失败', { cause: e })
  }
}

// load() 的调用方仍需 await/catch 处理它返回的 Promise

fetch 对 HTTP 404/500 通常仍 resolve,需检查 response.ok;网络失败、响应体解析失败等通过 rejection 传播。try/catch 不会自动接住稍后 timer 回调中的 throw 或未 await 的 Promise rejection。

return promise 会把 Promise 交给调用方,本地 catch 不会捕获其后续拒绝;若需要在当前 try 内处理,应 return await promise。

finally 的正常完成保留原结果;其中 return/throw 会覆盖原来的返回或异常。它不是进程退出、页面关闭或无限挂起时的持久清理保证。

工程实践

  • 区分可恢复与不可恢复
  • 错误信息带上下文(SKU id、请求号)
  • 不要空 catch
  • UI 层转用户可读,日志层保留技术细节

本节总结

try/catch 是控制流工具,不是日志框架;与 Promise/async 边界一起设计才完整。

自测题

  1. finally 里 return 有何风险?
  2. 为什么 try/catch 包 fetch().then() 不够?
参考答案
  1. 会覆盖此前的返回值,也可把原本抛出的异常变成正常返回;finally 中再次 throw 则替换原异常。\
  2. then 异步,错误在后续微任务;需 await 或 catch。
创建于 2025/1/1 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本