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

无需try catch如何实现JavaScript全局错误捕获

LWC单页应用全局JavaScript错误捕获落地方案

你之前使用window.onerror仅返回"Script error."、行号列号为0的问题,除了跨源脚本的同源策略限制,还有一个核心原因:window.onerror仅在事件冒泡阶段触发,LWC的Shadow DOM隔离边界会阻断错误事件冒泡到window对象,因此无法拿到组件内部的完整错误信息。
不需要给每个组件的代码单独包裹try/catch,以下方案组合使用可以覆盖绝大多数前端错误场景:

1. 用捕获阶段的全局error事件替代window.onerror

该方案可以覆盖所有同步运行时错误、静态资源(脚本/图片/样式)加载错误,监听注册在事件捕获阶段,不会被Shadow DOM边界拦截。
在应用最顶部的初始化入口(必须在所有业务组件加载前执行)注册监听:

window.addEventListener('error', (event) => {
  event.preventDefault();
  const errorLog = {
    message: event.message,
    source: event.filename,
    line: event.lineno,
    column: event.colno,
    stack: event.error?.stack || '',
    errorType: 'runtime error'
  };
  // 资源加载错误识别
  if (event.target && (event.target.src || event.target.href)) {
    errorLog.resourceUrl = event.target.src || event.target.href;
    errorLog.errorType = 'resource load error';
  }
  // 替换为自身业务的日志上报逻辑
  console.log('全局捕获错误:', errorLog);
}, true); // 第三个参数必须传true,开启捕获阶段监听

如果你的应用加载了跨源托管的脚本资源,需要给对应<script>标签添加crossorigin="anonymous"属性,同时静态资源服务配置匹配当前域名的Access-Control-Allow-Origin响应头,才能拿到跨源脚本的完整错误栈,否则浏览器会自动将错误信息脱敏为"Script error."。

2. 注册unhandledrejection事件捕获异步Promise错误

全局error事件无法捕获未处理的Promise rejection,包括async/await抛出的错误、未加catch的fetch/接口请求错误等,需要单独注册监听,同样使用捕获阶段:

window.addEventListener('unhandledrejection', (event) => {
  event.preventDefault();
  const errorLog = {
    message: typeof event.reason === 'object' ? event.reason.message : String(event.reason),
    stack: event.reason?.stack || '',
    errorType: 'unhandled promise rejection'
  };
  // 复用统一的日志上报逻辑
  console.log('全局捕获异步错误:', errorLog);
}, true);

3. 实现LWC原生全局错误边界

LWC框架本身提供了errorCallback生命周期钩子,专门用于捕获子组件在渲染、生命周期执行、事件回调过程中抛出的错误,不会受Shadow DOM隔离或沙箱限制,拿到的错误栈完全准确。
你只需要实现一个根级错误边界组件,将所有业务组件作为子元素包裹即可:

// globalErrorBoundary.js
import { LightningElement } from 'lwc';
export default class GlobalErrorBoundary extends LightningElement {
  hasRenderError = false;
  errorDetail = null;

  // 子组件抛错时框架会自动触发该钩子
  errorCallback(error, stackTrace) {
    this.hasRenderError = true;
    this.errorDetail = {
      message: error.message,
      stack: stackTrace
    };
    // 复用统一日志上报逻辑
    console.log('LWC框架捕获组件错误:', this.errorDetail);
  }
}

对应模板文件配置错误降级UI,避免整个应用白屏:

<!-- globalErrorBoundary.html -->
<template>
  <template if:false={hasRenderError}>
    <slot></slot> <!-- 插槽挂载所有业务路由、业务组件 -->
  </template>
  <template if:true={hasRenderError}>
    <div class="error-container">
      页面加载异常,请刷新后重试
    </div>
  </template>
</template>

4. 宏任务API包装补漏

部分LWC运行时(比如Salesforce平台沙箱)会拦截setTimeout、setInterval、requestAnimationFrame等宏任务回调的错误冒泡,导致全局事件监听拿不到对应错误,可以在入口处统一包装这类API,将错误主动抛到全局捕获链路:

// 以setTimeout为例,其余宏任务API逻辑一致
const originSetTimeout = window.setTimeout;
window.setTimeout = (cb, delay, ...args) => {
  return originSetTimeout(() => {
    try {
      cb.apply(this, args);
    } catch (err) {
      window.dispatchEvent(new ErrorEvent('error', {
        error: err,
        message: err.message
      }));
    }
  }, delay);
};

注意:如果你的LWC应用运行在Salesforce官方平台沙箱中,window全局事件的监听能力会受平台权限限制,优先使用LWC原生的errorCallback错误边界作为核心捕获方案,其余方案作为补充。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:03:18