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

如何提前加载JS模块类以优先捕获页面错误?

可行的错误监控方案

方案1:改用同步脚本加载(最直接,无延迟)

把ErrorReporter写成普通同步脚本而非ES模块。普通<script>标签默认同步执行,放在<head>最顶部就能优先于其他代码初始化错误监听,不会错过前置错误。

步骤:

  1. 修改ErrorReporter.js为非模块脚本,直接实例化并初始化:
class ErrorReporter {
  constructor() {
    this.errors = [];
    this.#setupListeners();
  }

  #setupListeners() {
    // 监听普通脚本错误
    window.addEventListener("error", (event) => {
      this.errors.push({
        message: event.message,
        filename: event.filename,
        line: event.lineno,
        column: event.colno,
        stack: event.error?.stack
      });
    });

    // 监听未捕获的Promise错误
    window.addEventListener("unhandledrejection", (event) => {
      this.errors.push({
        type: "unhandledrejection",
        message: event.reason?.message || "未处理的Promise拒绝",
        reason: event.reason,
        stack: event.reason?.stack
      });
    });

    // 页面卸载时发送错误
    window.addEventListener("beforeunload", () => {
      if (this.errors.length) {
        // 使用sendBeacon确保请求不被页面中断
        navigator.sendBeacon("/api/report-errors", JSON.stringify(this.errors));
      }
    });
  }
}

// 直接实例化,自动启动监听
window.errorReporter = new ErrorReporter();
  1. 在HTML的<head>最顶部引入该脚本:
<head>
  <script src="ErrorReporter.js"></script>
  <!-- 其他脚本、样式等 -->
</head>

方案2:保留ES模块+临时错误缓存(兼容模块需求)

如果必须用ES模块,可通过内联脚本先注册临时错误监听,提前缓存模块加载前的错误,等模块初始化后再合并到ErrorReporter中,避免遗漏。

步骤:

  1. 在HTML的<head>最顶部添加内联临时监听:
<head>
  <script>
    // 临时缓存模块加载前的错误
    window.__tempErrors = [];
    
    // 临时监听普通错误
    const tempErrorHandler = (event) => {
      window.__tempErrors.push({
        message: event.message,
        filename: event.filename,
        line: event.lineno,
        column: event.colno,
        stack: event.error?.stack
      });
    };
    window.addEventListener("error", tempErrorHandler);
    
    // 临时监听Promise错误
    const tempRejectionHandler = (event) => {
      window.__tempErrors.push({
        type: "unhandledrejection",
        message: event.reason?.message || "未处理的Promise拒绝",
        reason: event.reason,
        stack: event.reason?.stack
      });
    };
    window.addEventListener("unhandledrejection", tempRejectionHandler);
    
    // 存下临时处理器,方便后续移除
    window.__tempErrorHandlers = { tempErrorHandler, tempRejectionHandler };
  </script>
  <!-- 加载你的模块脚本 -->
  <script type="module" src="ErrorReporter.js"></script>
</head>
  1. 修改ErrorReporter.js模块,合并临时错误并替换监听:
export class ErrorReporter {
  constructor() {
    // 合并临时缓存的错误
    this.errors = [...window.__tempErrors];
    // 移除临时监听,避免重复收集
    const { tempErrorHandler, tempRejectionHandler } = window.__tempErrorHandlers;
    window.removeEventListener("error", tempErrorHandler);
    window.removeEventListener("unhandledrejection", tempRejectionHandler);
    
    this.#setupListeners();
    // 清理临时变量
    delete window.__tempErrors;
    delete window.__tempErrorHandlers;
  }

  #setupListeners() {
    // 注册正式的错误监听
    window.addEventListener("error", (event) => {
      this.errors.push({
        message: event.message,
        filename: event.filename,
        line: event.lineno,
        column: event.colno,
        stack: event.error?.stack
      });
    });

    window.addEventListener("unhandledrejection", (event) => {
      this.errors.push({
        type: "unhandledrejection",
        message: event.reason?.message || "未处理的Promise拒绝",
        reason: event.reason,
        stack: event.reason?.stack
      });
    });

    window.addEventListener("beforeunload", () => {
      if (this.errors.length) {
        navigator.sendBeacon("/api/report-errors", JSON.stringify(this.errors));
      }
    });
  }
}

// 实例化并挂载到全局
window.errorReporter = new ErrorReporter();

关键注意事项

  • 用navigator.sendBeacon替代普通请求:beforeunload事件中,普通fetch或XMLHttpRequest可能因为页面卸载被浏览器中断,sendBeacon是浏览器专门为这类场景设计的,会异步发送请求且不阻塞页面卸载,成功率更高。
  • 覆盖两种错误类型:除了error事件(普通脚本错误),务必监听unhandledrejection事件,捕获未处理的Promise错误,避免遗漏这类常见错误。

内容的提问来源于stack exchange,提问作者Jacob Chmielowiec

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:44:54