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

Ric*_*omi 11 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); };
Run Code Online (Sandbox Code Playgroud)

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

f(); // f is undefined
Run Code Online (Sandbox Code Playgroud)

结果是通常的"未捕获的ReferenceError:f未定义(...)"错误消息,但它没有通过我的全局onerror处理程序记录.

MDN页面说自从v40以来Chrome一直支持这个API,但navigator.serviceWorker.onerror最初是未定义的,这让我相信它没有实现.有人熟悉这个吗?

ton*_*y19 11

也许您试图像这样onerrornavigator.serviceWorker容器上设置处理程序:

// no effect outside service worker script
navigator.serviceWorker.onerror = function() {...};
Run Code Online (Sandbox Code Playgroud)

错误处理程序必须设置一个服务人员脚本中使用self.onerror(self是一个特殊的变量/属性,这里指代ServiceWorkerGlobalScope).该onerror回调只提供一条错误消息.

// inside service worker script
self.onerror = function(message) {
  console.log(message);
};
Run Code Online (Sandbox Code Playgroud)

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

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

这是一个演示.确保从DevTools> Resources> Service Workers(左侧面板)中删除服务工作者,因为它将填充这些失败的服务工作者注册:

在此输入图像描述

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

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

更新:

那么当MDN描述ServiceWorkerContainer接口时,那是指self(ServiceWorkerGlobalScope)而不是navigator.serviceWorker

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

正如GitHub(#198)中所讨论的那样,服务工作者工作组决定onerrorServiceWorkerContainer服务工作者实例迁移到服务工作者实例:slightlyoff/ServiceWorker

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

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

然后在相关问题(slightlyoff/ServiceWorker#104)中有一个后续评论表明onerror对容器缺乏用处:

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

关于用例的思考(从#198开始)......

navigator.serviceWorker.onerror或者navigator.serviceWorker.pending.onerror(以它为准)对于将错误记录回服务器没有用,因为错误可能发生在任何页面的生命周期之外.onerror在工人内部本身就是最好的.

.pending.onerror如果您为响应更新而更新UI,则非常有用.所以也许它更好statechange,尽管你需要在某处放置错误信息.

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

  • 我为此创建了一个 [GitHub 问题](https://github.com/slightlyoff/ServiceWorker/issues/912)。 (2认同)