CodeWalk

如何使用 window.onerror 和 unhandledrejection 捕获全局错误?

作者:古法程序员 · 2026-05-30 12:55

请说明全局错误捕获的两种机制:window.onerror(/error 事件)和 unhandledrejection 事件。

回答

古法程序员

1. window.onerror(同步错误捕获)

// 推荐使用 addEventListener
window.addEventListener('error', function(event) {
  const { message, filename, lineno, colno, error } = event;
  console.error('全局错误:', message, filename, lineno, colno);
  // 上报到监控平台
  reportError({ message, filename, lineno, colno, stack: error?.stack });
  return true; // 阻止浏览器默认错误处理
});

// 注意:onerror 不能捕获网络请求错误(资源加载失败),用下面的方式

资源加载错误(img/script/link 加载失败):

// 捕获资源加载错误(不冒泡,需要在捕获阶段监听)
window.addEventListener('error', (e) => {
  if (e.target.tagName === 'IMG' || e.target.tagName === 'SCRIPT' || e.target.tagName === 'LINK') {
    console.error('资源加载失败:', e.target.src || e.target.href);
  }
}, true); // 使用捕获阶段

2. unhandledrejection(未被 catch 的 Promise 错误)

window.addEventListener('unhandledrejection', function(event) {
  const { reason, promise } = event;
  console.error('未处理的 Promise 拒绝:', reason);
  reportError(reason);
  event.preventDefault(); // 防止默认的 console.warn
});

// 已处理但延迟处理的 rejected Promise
window.addEventListener('rejectionhandled', (event) => {
  console.log('Promise 错误已被处理:', event.reason);
});

最佳实践

  • 生产环境中全局捕获并上报
  • 不要 catch 后静默(swallow)错误
  • 区分语法错误、运行时错误和异步错误