Pio*_*ski 29 javascript angularjs angular-promise angular-providers angularjs-1.6
我有一个AngularJS代码:
service.doSomething()
.then(function(result) {
//do something with the result
});
Run Code Online (Sandbox Code Playgroud)
在AngularJS 1.5.9中,当我在该.then()部分中有错误时:
service.doSomething()
.then(function(result) {
var x = null;
var y = x.y;
//do something with the result
});
Run Code Online (Sandbox Code Playgroud)
我收到明确的错误消息:
TypeError:无法读取null的属性"y"
但是在版本1.6中使用相同的代码我得到了一个不同的错误:
可能是未处理的拒绝:{}未定义
我知道这与此更改有关,通过添加.catch()块,单个解决方案非常简单:
service.doSomething()
.then(function(result) {
var x = null;
var y = x.y;
//do something with the result
})
.catch(console.error);
Run Code Online (Sandbox Code Playgroud)
现在我再次拥有我想要的东西:
TypeError:无法读取null的属性"y"
但是如何在不在.catch()每个地方添加块的情况下为整个应用程序获得相同的结果(更详细的错误)?
我测试了建议的解决方案,通过添加:
$qProvider.errorOnUnhandledRejections(false);
Run Code Online (Sandbox Code Playgroud)
但有了这种情况甚至更糟 - 我在控制台中没有任何东西!错误被某处吞没,根本没有记录.我不确定AngularJS 1.6或我的配置是否有问题.
您是否有任何想法如何从1.5.9版"恢复"日志记录行为?
编辑:
添加定制错误处理程序
.factory('$exceptionHandler', function($log) {
return function(exception, cause) {
$log.warn(exception, cause);
};
})
Run Code Online (Sandbox Code Playgroud)
根本没有帮助.在错误处理程序中,我已经收到"包装"错误.
gka*_*pak 18
这已通过修复($ q)修复:将回溯添加到未处理的承诺拒绝 - 提交316f60f,修复程序包含在v1.6.1版本中.
And*_*kyi 15
第一个选项只是隐藏errorOnUnhandledRejections在$ qProvider配置中的disablinconfiguration错误,如同Cengkuru Michael建议:
app.config(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
Run Code Online (Sandbox Code Playgroud)
但这样只会关闭日志记录.错误本身将保留
在这种情况下,更好的解决方案是 - 使用.catch()方法处理拒绝:
service.doSomething()
.then(function (response) {})
.catch(function (err) {});
Run Code Online (Sandbox Code Playgroud)
有用的链接:
这些信息有助于我追踪(在我的情况下)创建承诺而不添加错误处理程序的原因。我发现它被埋在对问题#2889“ Angular 1.5.9可能未处理的拒绝”的讨论中。
要点是修补程序,$q以在创建promise时缓存堆栈跟踪,以便在触发错误时可以对其进行检索。
为此,请插入以下代码以装饰$q您的角度应用顶部附近的地方:
// Decorate the $q service when app starts
app.decorator('$q', ["$delegate", function($delegate) {
// Create a new promise object
var promise = $delegate.when();
// Access the `Promise` prototype (nonstandard, but works in Chrome)
var proto = promise.__proto__;
// Define a setter for `$$state` that creates a stacktrace
// (string) and assigns it as a property of the internal `$$state` object.
Object.defineProperty(proto, '$$state', {
enumerable: true,
set: function(val) {
val.stack = new Error().stack;
this._$$state = val;
},
get: function() {
return this._$$state;
}
});
return $delegate;
}]);
Run Code Online (Sandbox Code Playgroud)
然后在角度代码中搜索消息“可能未处理的拒绝”,并在该行上放置一个断点。当达到断点时,toCheck.stack在控制台上打印出值,您将看到以下内容:
>> toCheck.stack
"set@http://localhost:8000/js/dual-site.js:18:19
Promise@http://localhost:8000/js/angular.js:17008:22
then@http://localhost:8000/js/angular.js:17016:20
catch@http://localhost:8000/js/angular.js:17026:14
SyncStrategy.prototype.send@http://localhost:8000/js/angular-state-machine.js:436:24
StateMachine/this.send@http://localhost:8000/js/angular-state-machine.js:235:16
Run Code Online (Sandbox Code Playgroud)
令人反感的代码是调用angular的catch / then函数的帧。
| 归档时间: |
|
| 查看次数: |
46869 次 |
| 最近记录: |