【问题标题】:How does global error handling work in service workers?全局错误处理如何在 Service Worker 中工作?
【发布时间】:2016-10-10 17:14:10
【问题描述】:

我找到了https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/onerror,上面写着:

ServiceWorkerContainer 接口的 onerror 属性是一个 每当关联中发生错误事件时触发事件处理程序 服务人员。

但是我无法在 Chrome (v51) 中使用它。在主应用程序的范围内,我从控制台运行了以下代码:

navigator.serviceWorker.onerror = function(e) { console.log('some identifiable string' + e); };

然后在主动服务工作者的范围内我触发了一个任意错误:

f(); // f is undefined

结果是通常的“Uncaught ReferenceError: f is not defined(...)”错误消息,但它没有通过我的全局 onerror 处理程序记录。

MDN 页面说 Chrome 从 v40 开始就支持这个 API,但是 navigator.serviceWorker.onerror 最初是未定义的,这让我相信它没有实现。有谁熟悉这个吗?

【问题讨论】:

  • "initially undefined" - 你的意思是它的值确实是undefined(这是合理的),还是该属性根本不存在?跨度>
  • @Bergi 它的值为undefined,这让我觉得很不寻常,因为 window.onerror 最初是null。编辑:我仔细检查过,属性也不存在'onerror' in navigator.serviceWorker // false

标签: javascript google-chrome service-worker


【解决方案1】:

也许您尝试像这样在navigator.serviceWorker 容器上设置onerror 处理程序:

// no effect outside service worker script
navigator.serviceWorker.onerror = function() {...};

错误处理程序必须在服务工作者脚本中使用self.onerror 设置(self 是此处引用ServiceWorkerGlobalScope 的特殊变量/属性)。 onerror 回调仅提供错误消息。

// inside service worker script
self.onerror = function(message) {
  console.log(message);
};

或者,您可以侦听 service worker 的 error 事件,其中包括一个包含错误位置的 ErrorEvent

// inside service worker script
self.addEventListener('error', function(e) {
  console.log(e.filename, e.lineno, e.colno, e.message);
});

这是demo。请务必从 DevTools > Resources > Service Worker(左侧面板) 中删除服务工作者,因为它将填充这些失败的服务工作者注册:

我已在 Service Worker 实例中验证了以下浏览器支持 onerror

  • Chrome 51(稳定版)和 53(金丝雀版)
  • 火狐 47
  • Opera 38(稳定版)和 39(开发版)

更新

所以当MDN描述ServiceWorkerContainer接口时,指的是selfServiceWorkerGlobalScope)而不是navigator.serviceWorker

我认为这仅适用于 onerror 属性(可能也适用于那里的其他事件),我猜该规范尚未更新以反映商定的实施......

Service Worker 工作组已决定将 onerrorServiceWorkerContainer 移至 Service Worker 实例,如 GitHub (slightlyoff/ServiceWorker #198) 中所述:

kinu于 2014 年 4 月 2 日发表评论

sgtm2.对于错误报告(onerror 的东西),我们可能会做类似的事情吗?例如。将 .onerror 处理程序从容器移动到 SW 对象,以便 doc 可以明确知道错误来自哪个 SW(尽管它可能需要将处理程序附加到多个 SW)。

然后在相关问题 (slightlyoff/ServiceWorker #104) 中有一条后续评论表明容器上的 onerror 没有用处:

jakearchibald 于 2014 年 4 月 3 日发表评论

考虑用例(从#198开始)……

navigator.serviceWorker.onerrornavigator.serviceWorker.pending.onerror(无论哪个)对于将错误记录回服务器没有用处,因为错误可能在任何页面的生命周期之外发生。 onerror 在 worker 内部是最好的。

.pending.onerror 在您更新 UI 以响应更新时很有用。所以也许最好是statechange,尽管您需要在某个地方放置错误消息。

这会留下在创建 SW 实例之前发生的错误。 AppCache 有一个错误事件,涵盖与网络相关的更新失败,以及解析失败。但是,我们将再次丢失页面生命周期之外发生的任何错误。

【讨论】:

  • 感谢您的回答。所以当MDN描述ServiceWorkerContainer接口时,指的是selfServiceWorkerGlobalScope)而不是navigator.serviceWorker
  • 没问题。我不确定一定是这样。 onerror 事件处理程序(可能还有其他事件)恰好是这样。根据我从 2014 年发现的 GitHub 讨论,我相信这些事件实际上已被移动,但文档没有更新。为了清楚起见,我会更新我的答案。
  • 非常有趣。在这种情况下,不仅文档没有更新,而且规范本身也不正确:w3.org/TR/service-workers/…
  • 我为此创建了一个GitHub issue
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
相关资源
最近更新 更多