javascript错误处理怎样捕获异常?【教程】

14次阅读

try-catch只捕获同步异常,如throw、TypeError等;异步错误需用async/await或unhandledrejection监听;window.onerror和error事件补全局错误,但Web Worker、跨域iframe等错误无法捕获。

javascript错误处理怎样捕获异常?【教程】

try-catch 能捕获哪些错误?

它只捕获**同步执行中抛出的异常**,比如 throw new Error()、类型错误(TypeError)、引用错误(ReferenceError)等。异步代码(如 setTimeoutfetchpromise 回调)里直接 throw,不会被外层 try-catch 捕获。

常见误判场景:

  • 写了 try { fetch('/api').then(...)} catch(e) {...} —— 这个 catch 实际捕获不到 Promise 内部错误
  • jsON.parse('invalid') 会触发,但 json.parse(undefined) 也会(因为传了非字符串
  • 箭头函数中忘记写 return,导致意外返回 undefined,后续调用 .mapTypeError: Cannot read Property 'xxx' of undefined —— 这类错误能被捕获,但根源在逻辑,不是语法

async/await 怎么配合 try-catch?

这是目前最接近“同步写法捕获异步错误”的方式。关键点:await 必须在 async 函数内,且被 await 的 Promise 被 reject 时,会以异常形式抛出,进 catch 块。

正确写法示例:

立即学习Java免费学习笔记(深入)”;

async function loadData() {   try {     const res = await fetch('/api/users');     if (!res.ok) throw new Error(`HTTP ${res.status}`);     const data = await res.json();     return data;   } catch (err) {     console.error('加载失败:', err.message);     // 这里能捕获 fetch 网络失败、JSON 解析失败、手动 throw 的错误   } }

注意:

  • 不要对 fetch 本身加 try-catch 就以为万事大吉 —— 它只拒绝网络级错误(如离线),404500 仍返回成功 Promise,需手动检查 res.ok
  • await Promise.reject(new Error()) 会被捕获;但 Promise.reject() 不 await,就不会

window.onerror 和 window.addEventListener(‘error’) 有什么区别

它们补的是 try-catch 漏掉的“全局异常”:脚本加载失败、资源加载错误(javascript错误处理怎样捕获异常?【教程】 404)、未捕获的 Promise rejection、跨域脚本错误(此时 error 信息被浏览器抹为 Script error.)。

实操建议:

  • window.addEventListener('error', handler) 捕获资源加载类错误(如图片、css 加载失败),它比 window.onerror 更早触发,且能拿到 event.target
  • 必须同时监听 unhandledrejection 事件来捕获没被 catch 的 Promise 错误:
window.addEventListener('unhandledrejection', event => {   console.error('未处理的 Promise 拒绝:', event.reason);   event.preventDefault(); // 阻止默认控制台报错(可选) });

注意:unhandledrejection 在 Promise 被 reject 且没有 .catch 或 await 后无 try-catch 时才触发 —— 不是所有 reject 都算“未处理”。

为什么有些错误就是抓不到?

根本原因在于 javaScript 错误分类和运行时机制。以下几类基本无法用常规 JS 错误处理捕获:

  • console.error() 不是错误,只是日志,不会触发任何异常机制
  • Web Worker 内部错误不会冒泡到主页面,需在 worker 内单独监听 onerror
  • iframe 中的脚本错误受同源策略限制,跨域 iframe 的错误信息不可读(只显示 Script error.
  • 某些浏览器扩展注入的脚本崩溃、或页面被强制 kill(如 ios safari 内存回收)—— 这些已脱离 JS 执行上下文

真正容易被忽略的点:错误对象stack 属性在压缩后可能指向混淆后的文件行号,上线前确保 source map 正确上传并被监控平台识别。否则你看到的 at a.js:1:1 没有任何调试价值。

text=ZqhQzanResources