如何找到被拒绝的 Promise 的来源

问题描述 投票:0回答:1

最近,我们发现 Sentry 中标题为

Event CustomEvent (type=unhandledrejection) captured as promise rejection
的错误急剧增加。根据迄今为止的研究,看起来 Promise 在代码中的某个地方被拒绝了,但我们还没有找到发生这种情况的位置。

我已经添加了下面的代码来记录跟踪条目,其中包含有关被拒绝事件的一些信息,但显然

reason
undefined
。我知道侦听器参数上还有一个
promise
属性,但我不知道如何从该对象获取任何有用的信息。是否可以确定承诺的来源?如果可以,如何确定?

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

更新

尝试使用

window.addEventListener('unhandledrejection', console.error)
,它确实按预期工作,但不幸的是,没有包含比我自己的处理程序中可用的更多信息。

受评论的启发,还尝试对 CustomEvent 构造函数进行猴子修补,如下所示。当通过调用

window.dispatch(new CustomEvent('unhandledrejection'))
在控制台中进行测试时,堆栈出现,但在生产中它不会显示在传入事件上。我认为这是由以另一种方式创建的 CustomEvent 引起的,尽管我对 Javascript 不够熟悉,无法肯定地说。

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;
javascript promise unhandled-promise-rejection
1个回答
0
投票

您是否也尝试过按照 Pavlo Sobochuk 的建议对 Promise 进行猴子修补?下面的猴子补丁记录了当有人无缘无故拒绝承诺时的堆栈。

const ecmaPromise = Promise;
Promise = class extends ecmaPromise {
  constructor(executor) {
    super(function(resolve, reject) {
      executor(resolve, function(reason) {
        if (reason === undefined)
          reason = {
            stack: new Error().stack
          };
        reject(reason);
      });
    });
  }
}
window.addEventListener('unhandledrejection', console.error);
new Promise(function(resolve, reject) {
  setTimeout(reject, 100);
});

© www.soinside.com 2019 - 2024. All rights reserved.