You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保window.onerror触发并捕获所有前端全局错误

问题原因分析

  • React合成事件与渲染流程的内部错误拦截:React 16及以上版本会默认捕获所有合成事件回调(如onClick、onChange)、组件渲染流程、生命周期钩子中抛出的同步错误,仅输出到控制台,不会冒泡到window.error事件,避免单个组件错误导致整个应用崩溃,这是手动抛出错误无法触发监听的核心原因。
  • Promise类错误未匹配对应监听事件:fetch返回500属于HTTP业务错误,本身不会触发Promise reject,只有网络异常、跨域等场景才会默认抛出Promise错误;且所有Promise链中未被catch的错误,不会触发window.error事件,只会触发window.unhandledrejection事件,仅监听error事件自然无法捕获这类错误。
  • 异步上下文的错误隔离:如果throw new Error代码位于setTimeout、未await的async函数等异步执行上下文,也可能因为上层逻辑隐式捕获,导致错误无法冒泡到全局。

解决方案

1. 补全全局事件监听

同时监听两类全局错误事件,覆盖同步运行时错误和未处理的Promise错误:

// 监听同步运行时错误
window.addEventListener('error', (event) => {
  alert(`同步错误:${event.message}`)
  // 如需阻止控制台打印默认错误,可开启下行配置
  // event.preventDefault()
})

// 监听Promise未捕获错误(含fetch、async函数抛出的未处理错误)
window.addEventListener('unhandledrejection', (event) => {
  alert(`Promise错误:${event.reason?.message || event.reason}`)
  // 如需标记错误已处理、阻止控制台报错,可开启下行配置
  // event.preventDefault()
})

针对fetch的HTTP错误需要手动抛出才会被全局捕获,示例如下:

fetch('/api/xxx')
  .then(res => {
    // 手动判断HTTP状态码,非2xx状态抛出错误
    if (!res.ok) throw new Error(`HTTP错误:${res.status}`)
    return res.json()
  })

2. 捕获React内部错误

React内部的错误不会冒泡到全局window,需要用官方提供的错误边界(Error Boundary)组件捕获,示例如下:

import React from 'react';

class ErrorBoundary extends React.Component<{children: React.ReactNode}, {hasError: boolean}> {
  constructor(props: {children: React.ReactNode}) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: Error) {
    // 此处可对接全局错误处理逻辑,如错误上报、弹窗提示等
    alert(`React内部错误:${error.message}`);
  }

  render() {
    if (this.state.hasError) {
      return <h1>页面出现异常,请刷新重试</h1>;
    }
    return this.props.children;
  }
}

在应用根组件外层包裹错误边界即可捕获全量React内部错误:

// 入口文件示例
import { createRoot } from 'react-dom/client';
import App from './App';

const root = createRoot(document.getElementById('root')!);
root.render(
  <ErrorBoundary>
    <App />
  </ErrorBoundary>
);

3. 特殊场景兜底

如使用React Router等路由框架,需将错误边界放在路由组件外层,确保路由切换时的错误也能被捕获;React 18并发模式下的异步渲染错误也可通过错误边界正常捕获。

内容的提问来源于stack exchange,提问作者Yisroel M. Olewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:36:02