7

我一直在使用 Zone.js,我想为任何未捕获的异常设置日志记录。我可以设置一个错误处理程序,如下所示:

window.onerror = function(e) { 
    //send an error report to the server
}

但是如果在 Promise 中抛出异常,这将不起作用。Zone 错误处理程序的好处是它与 Promises 挂钩并触发其中的异常,但除了覆盖一堆之外,我找不到在创建 Zone 后实际覆盖或添加错误处理程序的方法区域上的私有字段。

是否有一个实际的区域 API 可用于更新错误处理程序,或者我是否必须更改构建根区域的 polyfill 或覆盖私有字段或类似的东西?

4

3 回答 3

3

对于从 zone.js 0.78 开始的 promise 未捕获的 promise 错误,您可以使用此 API。

https://github.com/angular/zone.js/pull/627

 window.addEventListener("unhandledrejection", function (event) {
  console.warn("WARNING: Unhandled promise rejection. Shame on you! Reason: "
               + event.reason);
});

window.addEventListener("rejectionhandled", function (event) {
  console.log("Promise rejected! Reason: " + reason);
});
于 2017-03-12T13:10:22.947 回答
2

你可以尝试这样的事情:

<html>
<head>
<script src="https://unpkg.com/zone.js?main=browser"></script>
<script>
Zone.current.fork({
    onHandleError: function(parentZoneDelegate, currentZone, targetZone, error) {
        console.log("Error handled by zone: " + error);
    }
}).run(function () {
    setTimeout(function () {
        console.log("In zone setTimeout")
        throw new Error("Throw in zone setTimeout"); 
    }, 0);
    console.log("Directly in zone");
});
</script>
</head>
<body>
</body>
</html>

这将在由指定的自定义处理程序中捕获异常onHandleError并产生如下输出:

Directly in zone (test1.html:14)
In zone setTimeout (test1.html:11 )
Error handled by zone: Error: Throw in zone setTimeout (test1.html:7)

但是,如果直接在区域中引发异常,它似乎不起作用。我已经提交并发布了这个问题。

于 2016-09-07T17:34:35.653 回答
2

如果要处理所有类型的未处理异常(在简单区域、setTimeouts 或 Promises 等中),则必须使用runGuarded方法而不是on Zonerun

这是一个示例代码:

Zone.current.fork({
  name: 'MyGlobalErrorLoggerZone',
  onHandleError: function(parentZoneDelegate, currentZone, targetZone, error){
     console.log(error);
     // send it to server here.
  }
})
.runGuarded(function(){
   // your application code here...
   // handles errors inside promises
   new Promise(function(resolve, reject){
        reject('Rejecting: Some Error');
   });
    console.log('Running in Zone...', Zone.current.name);
    // handles errors inside timeouts/intervals
    setTimeout(function(){
            console.log('after 1 sec', Zone.current.name);
            throw new Error('This is an error. Make your self log me please.');
    }, 1000);
    // Handles errors throw directly in zone too.
    throw new Error('oops, one more error');
});
于 2018-03-24T09:55:28.270 回答