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

如何定位未处理Promise拒绝的来源?及排查遇阻的异常问题

定位Sentry中陡增的Event CustomEvent (type=unhandledrejection)错误来源

近期Sentry中标题为Event CustomEvent (type=unhandledrejection) captured as promise rejection的错误数量陡增,初步排查发现代码存在Promise被拒绝的情况,但无法定位具体位置。

已添加如下代码跟踪拒绝事件,但reason值始终为undefined。已知监听参数包含promise属性,但不知道如何从中提取有效信息,想确认是否能确定Promise的来源,以及具体操作方法:

window.addEventListener('unhandledrejection', ({ reason }) => {
  ErrorManagement.addTrace({
    data: { reason },
    level: 'info',
    message: 'unhandledrejection caught',
    category: 'error',
  });
});

更新1

尝试直接用window.addEventListener('unhandledrejection', console.error),能正常执行,但没比自定义处理程序多提供信息。

受启发尝试通过猴子补丁修改CustomEvent构造函数,控制台测试window.dispatch(new CustomEvent('unhandledrejection'))时能显示堆栈,但生产环境无效,推测是CustomEvent创建方式不同,但不确定原因:

class CustomEventWithStack extends CustomEvent<any> {
  stack?;

  constructor(type: string, eventInitDict?: CustomEventInit) {
    super(type, eventInitDict);
    if (type === 'unhandledrejection') {
      this.stack = (new Error()).stack;
    }
  }
}
CustomEventWithStack.prototype = CustomEvent.prototype;
CustomEventWithStack.prototype.constructor = CustomEventWithStack;
CustomEvent = CustomEventWithStack;

更新2

进一步尝试猴子补丁修改Promise:

window.addEventListener('unhandledrejection', (event) => {
  ErrorManagement.addTrace({
    data: {
      reason: event.reason,
      stack: (event.promise as PromiseWithStack<any>).stack,
    },
    level: 'info',
    message: 'unhandledrejection caught',
    category: 'error',
  });
});

class PromiseWithStack<T> extends Promise<T> {
  stack = new Error().stack;

  constructor(executor: (resolve: any, reject: any) => void) {
    super((resolve, reject) => {
      executor(resolve, (reason: any) => {
        if (reason === undefined) {
          reject({ stack: new Error().stack });
        }
      });
    });
  }
}

window.Promise = PromiseWithStack;
const originalFetch = fetch;
window.fetch = (...args) => new PromiseWithStack((resolve, reject) => {
  originalFetch(...args).then(resolve, reject);
});

但触发了新错误:Cannot read properties of undefined (reading 'stack')。于是检查事件监听中传入的事件内容:

data: {
  reason: event.reason,
  eventClass: event.constructor.name,
  promiseType: typeof event.promise,
  promiseClass: event.promise?.constructor.name,
},

得到结果:

{
  "eventClass": "CustomEvent",
  "promiseType": "undefined"
}

现在产生新疑问:为什么CustomEvent会出现在'unhandledrejection'事件监听中?不确定是否需要单独提交新问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:02:12