16

问题

JSFiddle:http: //jsfiddle.net/missingno/Gz8Pe/2/

我有一些看起来像这样的代码:

var d = new Deferred();
d.resolve(17);
return d.then(function(){
     //do some stuff...
})
.then(function(){
    var obj = a_funtion_that_returns_null_on_IE();
    var x = obj.some_property; //BOOM!
});

问题是,当我在 IE 上时,我只能看到'obj' is null or not an object错误,没有任何对相应行号的引用,也没有调试器在有问题的行处停止(就像我希望的那样)。

这类问题使代码难以调试,而我现在能想到的唯一解决方案(弄乱控制流库或使用调试器或 console.log 进行逐步调试)是我宁可不用做。

我认为正在发生的事情

为了允许在触发链后添加 errbacks,then将抢先捕获回调抛出的任何异常。我认为这是 IE 调试器没有停止错误或显示带有行号的通常错误消息的原因。

没有行号的错误消息来自控制流库:它提供了一个deferredOnError挂钩,每当捕获到异常并保存以供以后使用时都会调用该挂钩,默认行为是 console.error-ing 错误对象:

dojo.config.deferredOnError = function(err){
    //a chance to log the exception after it is captured by "then"
    //or do other things with it
    console.error(err);
}

可悲的是,我无法找到从 IE 中的错误对象获取行号或堆栈跟踪的方法,并且该挂钩的调用方式不允许我重新抛出异常并让它冒泡到顶层。

我想要的是

我希望有一种更好的方法来调试异步代码,然后一步一步地与调试器一起进行。在最好的情况下,一种让调试器在异常上停止的方法(就像它在未处理的异常上所做的那样),或者至少是一种从抛出的 Error 对象中获取行号或堆栈跟踪的方法。

4

3 回答 3

14

这适用于任何没有事先配置的框架,并且所有最近的浏览器都支持这一点。

Pause On Caught Exceptions:这实际上将停止 javascript 的执行,并将带您准确地知道有问题的代码在哪里,因为它正在发生。

Pause On Caught Exceptions

在 Chrome 中:

  1. Developer Tools,
  2. Sources tab,
  3. Pause on exceptions (stop-like icon) and then
  4. the Pause On Caught Exceptions checkbox
于 2014-11-11T19:11:17.697 回答
4

我最终做了什么

我在我的小型异步辅助函数库中添加了一个排序函数。它基本上运行一系列“then”调用,除了它添加了额外的中间步骤来重新抛出最终被 Deferreds 捕获的任何异常。它还接受一个可选的错误处理程序来捕获异常。

当我调用它时,它看起来像这样:

go([
    function(){
        return 17;
    },
    function(x){
        //return some stuff
    },
    function(){
         var obj = a_function_that_returns_null_on_IE();
         var x = obj.some_property; //BOOM!
    }
], function(){
    //an optional error handler
});

我这样做的另一个原因是我有很多代码需要与同步或异步代码同时工作(使用 Deferred.when 进行链接)。使用我的自定义函数让我可以使用单一、统一的语法,并且在异步情况下未捕获的错误与同步情况一致,其中不涉及延迟。我也认为不捕获错误是可以的,因为与一般情况不同,当我使用“go”时,我先验地知道将调用什么代码,因此如果有人需要捕获,则无需捕获异常他们在未来。

此外,使用自定义解决方案让我可以自由执行一些个人设计偏好:)


除此之外,我最终减少了我自己在整个代码库中生成的异常数量。在异步代码中管理异常比平常更烦人,有时通过返回 null 或错误代码来回退到处理错误条件更简单。

此外,我们确保我们自己创建的任何异常都是内置 Error 类的实例,而不是其他对象。原因是内置的 Error 类以一种跨浏览器的方式记录了生成它的行号和堆栈跟踪。

于 2012-04-27T18:35:30.243 回答
4

2016 solution

If you're using native ES Promises do absolutely nothing; Chrome automatically reports uncaught promise rejections in the console.

Notice how the caught one (Second fail) doesn't show anything but the uncaught rejection appears in the console after the code is done running.

于 2016-03-04T07:50:21.560 回答