【问题标题】:What does it mean when an unhandledrejection event does not contain a reason field?unhandledrejection 事件不包含原因字段是什么意思?
【发布时间】:2021-07-08 02:54:45
【问题描述】:

通过 Rollbar 跟踪我们应用的客户端错误。我们不断收到这个在 Safari 和 Chrome 中不是很有用的错误:

[unhandledrejection] error getting `reason` from event

我将此追踪到 Rollbar JS,当它无法找出 unhandledrejection 事件处理程序中的错误时,它最终创建了此消息。

function captureUnhandledRejections(window, handler, shim) {
  if (!window) { return; }

  if (typeof window._rollbarURH === 'function' && window._rollbarURH.belongsToShim) {
    window.removeEventListener('unhandledrejection', window._rollbarURH);
  }

  var rejectionHandler = function (evt) {
    var reason, promise, detail;
    try {
      reason = evt.reason;
    } catch (e) {
      reason = undefined;
    }
    try {
      promise = evt.promise;
    } catch (e) {
      promise = '[unhandledrejection] error getting `promise` from event';
    }
    try {
      detail = evt.detail;
      if (!reason && detail) {
        reason = detail.reason;
        promise = detail.promise;
      }
    } catch (e) {
      // Ignore
    }
    if (!reason) {
      reason = '[unhandledrejection] error getting `reason` from event';
    }

    if (handler && handler.handleUnhandledRejection) {
      handler.handleUnhandledRejection(reason, promise);
    }
  };
  rejectionHandler.belongsToShim = shim;
  window._rollbarURH = rejectionHandler;
  window.addEventListener('unhandledrejection', rejectionHandler);
}

https://github.com/rollbar/rollbar.js/blob/a9c567cd1886f177fa4719a0054bff8280928fce/src/browser/globalSetup.js#L80-L90

有没有人看到这是关于什么的?

【问题讨论】:

  • 是否应该删除 node.js 标签,因为这是客户端代码?
  • 噢!你是对的。我已删除我的 cmets,以免误导未来的读者。

标签: javascript node.js rollbar


【解决方案1】:

这只意味着这个脚本已经处理了一个被错误值拒绝的 Promise。

var handler = {
  handleUnhandledRejection( reason, promise ) {
    console.log( reason, promise );
  }
};

var rejectionHandler = function (evt) {
  var reason, promise, detail;
  try {
    reason = evt.reason;
  } catch (e) {
    reason = undefined;
  }
  try {
    promise = evt.promise;
  } catch (e) {
    promise = '[unhandledrejection] error getting `promise` from event';
  }
  try {
    detail = evt.detail;
    if (!reason && detail) {
      reason = detail.reason;
      promise = detail.promise;
    }
  } catch (e) {
    // Ignore
  }
  if (!reason) {
    reason = '[unhandledrejection] error getting `reason` from event';
  }
  if (handler && handler.handleUnhandledRejection) {
    handler.handleUnhandledRejection(reason, promise);
  }
};
window.addEventListener('unhandledrejection', rejectionHandler);

const buttons = document.querySelectorAll("button");
buttons[ 0 ].onclick = (evt) => {
  Promise.reject(false)
};
buttons[ 1 ].onclick = (evt) => {
  Promise.reject(true)
};
<button>reject with falsey reason</button>
<button>reject with truthy reason</button>

但此处理程序不会阻止事件的默认行为,因此您仍应在控制台中获得默认的未处理错误消息,并正确跟踪以虚假原因拒绝此 Promise 的函数。
如果你没有它,这意味着还有其他东西正在处理这个事件(并调用preventDefault())。

您可以通过在页面顶部插入您自己的处理程序来管理它,该处理程序将调用evt.stopImmediatePropagation()(请注意,capturewindow 没有帮助,您需要在坏处理程序之前附加您的处理程序) .

// before any other script runs
window.addEventListener('unhandledrejection', (evt) => evt.stopImmediatePropagation() );


// The one that would hide our trace
function badHandler(evt) {
  evt.preventDefault();
}
window.addEventListener('unhandledrejection', badHandler);


// let's make up a trace to follow
document.querySelector("button").onclick = (evt) => {
  triggerSomethingRejecting();
};
function triggerSomethingRejecting() {
  [0].forEach(() => Promise.reject(false) );
}
<button>reject</button>
<pre>
Check your browser's console to see the trace of the unhandled Promise
</pre>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 2019-02-24
    相关资源
    最近更新 更多