全局错误处理如何在服务工作者中工作?

时间:2016-06-09 21:16:17

标签: javascript google-chrome service-worker

我发现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未定义(...)"错误消息,但它没有通过我的全局onerror处理程序记录。

MDN页面说明自v40以来Chrome已支持此API,但navigator.serviceWorker.onerror最初未定义,这让我相信它未实现。有人熟悉这个吗?

1 个答案:

答案 0 :(得分:9)

也许您尝试在onerror容器上设置navigator.serviceWorker处理程序,如下所示:

// 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);
};

或者,您可以收听服务工作者的error事件,其中包含一个包含错误位置的ErrorEvent

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

这是一个demo。务必从 DevTools>中删除服务工作者。资源>服务工作者(在左侧面板上),因为它将填补这些失败的服务工作者注册:

enter image description here

我已经验证了以下浏览器在服务工作者实例中支持onerror

  • Chrome 51(稳定)和53(金丝雀)
  • Firefox 47
  • Opera 38(稳定)和39(开发者)

<强>更新

  

因此,当MDN描述ServiceWorkerContainer界面时,指的是selfServiceWorkerGlobalScope)而不是navigator.serviceWorker

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

服务工作者工作组决定将onerrorServiceWorkerContainer移动到服务工作者实例中,如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最适合。

     如果您要更新UI以响应更新,则

.pending.onerror非常有用。所以也许它作为statechange会更好,尽管你需要在某处放置错误信息。

     

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