如果库吞没所有异常,我如何调试我的异步,基于承诺的代码?

时间:2012-02-07 20:11:48

标签: javascript debugging dojo deferred promise

问题

的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中的错误对象获取行号或堆栈跟踪的方法,并且调用钩子的方式不允许我重新抛出异常并让它冒泡到toplevel。

我想要什么

我希望有一种更好的方法来调试异步代码,然后逐步调试调试器。在最好的情况下让调试器暂停异常的方法(就像在未处理的异常上一样)或至少可以通过获取行号或堆栈来自Error对象的跟踪

3 个答案:

答案 0 :(得分:12)

这适用于没有事先配置的任何框架,所有最近的浏览器都支持此功能。

Pause On Caught Exceptions:这实际上会阻止javascript的执行,并且会在问题代码发生的时候带你到位。

Pause On Caught Exceptions

在Chrome中:

  1. 开发人员工具
  2. 来源标签,
  3. 暂停例外(类似停止图标),然后
  4. 暂停捕获例外复选框

答案 1 :(得分: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类以一种跨浏览器的方式记录了它的生成位置的行号和堆栈跟踪。

答案 2 :(得分:3)

2016解决方案

如果您使用的是本机ES Promises,则绝对不做任何事; Chrome会自动在控制台中报告未被捕获的拒绝承诺。

"Uncaught Promise error" in Chrome dev tools

注意捕获的一个(Second fail)在代码运行完毕后,控制台中是否显示除了未被捕获的拒绝之外的任何内容。