简体   繁体   English

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

[英]How do I debug my asynchronous, promise based code if the library is swallowing all the exceptions?

The Problem 问题

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

I have some code that looks like this: 我有一些看起来像这样的代码:

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!
});

The problem is that when I am on IE all I can see are 'obj' is null or not an object errors, without any reference to the corresponding line number and without the debugger halting at the offending line (like I wish it would). 问题是,当我在IE上时,我只能看到'obj' is null or not an object错误, 没有任何对相应行号的引用,也没有调试器在违规行停止 (就像我希望的那样)。

This kind of issue is making the code a pain to debug and the only solutions I can think of right now (messing around with the control flow library or resorting to step-by-step debugging with the debugger or console.log) are things I would rather not have to do. 这种问题使得代码很难调试,我现在能想到的唯一解决方案(搞乱控制流程图或使用调试器或console.log进行逐步调试)是我的事情。宁可不必做。

What I think is going on 我的想法是怎么回事

In order to allow errbacks to be added after the chain is fired, then will preemptively catch any exceptions thrown by the callbacks. 为了允许在链被触发后添加errbacks, then将抢先捕获回调抛出的任何异常。 I think this is the reason for the IE debugger not halting on the error or showing the usual error message witht the line number in it. 我认为这是IE调试器没有停止错误或显示通常的错误消息的原因,其中包含行号。

The error messages without the line numbers are coming from the control-flow library: it provides a deferredOnError hook that is called whenever an exception is caught and saved for later and the default behaviour is console.error-ing the Error object: 没有行号的错误消息来自控制流库:它提供了一个deferredOnError钩子,只要捕获并保存以供日后使用,就会调用它,默认行为是console.error -ing Error对象:

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);
}

Sadly, I could not figure out a way to get the line number or stack trace from the error object in IE and the hook is called in a way that does not allow me to just rethrow the exception and let it bubble up to the toplevel. 遗憾的是,我无法找到从IE中的错误对象获取行号或堆栈跟踪的方法,并且以一种不允许我重新抛出异常并让它冒泡到顶层的方式调用钩子。

What I want 我想要的是

I want to have a better way to debug the async code then goind along with the debugger step-by-step. 我希望有一种更好的方法来调试异步代码,然后逐步调试调试器。 In the best case a way to have the debugger halt on the exceptions (as it does on unhandled exceptions) or at least a way to get line numbers or stack traces from the Error object that was thrown. 在最好的情况下,有一种方法可以让调试器暂停异常 (就像在未处理的异常上一样), 或者至少是抛出的Error对象获取行号或堆栈跟踪的方法

This works with any framework without prior configuration and all recent browsers support this. 这适用于没有事先配置的任何框架,所有最近的浏览器都支持此功能

Pause On Caught Exceptions: This will actually stop javascript's execution and will take you exactly where the problematic code is, as it's happening. 暂停捕获的异常:这实际上会阻止javascript的执行,并且会在问题代码发生的时候将其带到您的确切位置。

暂停捕获的异常

In Chrome: 在Chrome中:

  1. Developer Tools , 开发者工具
  2. Sources tab, 来源标签,
  3. Pause on exceptions (stop-like icon) and then 暂停异常 (类似停止的图标)然后
  4. the Pause On Caught Exceptions checkbox 暂停捕获例外复选框

What I ended up doing 我最终做了什么

I added a sequencing function to my mini library of async helper functions. 我在我的迷你辅助函数库中添加了一个排序函数。 It basically runs a sequence of "then" calls, except that it adds extra intermediate steps to rethrow any exceptions that end up being caught by the Deferreds. 它基本上运行一系列“then”调用,除了它添加了额外的中间步骤来重新抛出最终被Deferreds捕获的异常。 It also accepts an optional error handler to catch the exceptions. 它还接受一个可选的错误处理程序来捕获异常。

When I call it it looks like this: 当我打电话给它时,它看起来像这样:

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
});

Another reason that I did things this way is that I have lots of code that needs to work simultaneously with either sync or async code (using Deferred.when to do the chaining). 我这样做的另一个原因是我有很多代码需要同步和异步代码(使用Deferred.when进行链接)。 Using my custom function let me use a single, unified syntax and the errors not being captured in the async case is consistent with the sync case, where there are no Deferreds involved. 使用我的自定义函数让我使用单一,统一的语法,并且在异步情况下未捕获的错误与同步情况一致,其中不涉及延迟。 I also think its OK to not capture the error, since unlike in the general case, when I am using "go" I know a-priori what code will be called, so there is no need to capture exceptions for if someone needs to catch them in the future. 我也认为没有捕获错误是可以的,因为与一般情况不同,当我使用“go”时,我知道将会调用哪些代码,因此如果有人需要捕获,则无需捕获异常他们将来。

Also, using a custom solution gave me the freedom to enforce some personal design preferences :) 此外,使用自定义解决方案让我可以自由地执行一些个人设计偏好:)


In addition to that, I ended up reducing the amount of exceptions I generate myself throughout the code base. 除此之外,我最终减少了我在整个代码库中生成的异常数量。 Managing exceptions in async code is more annoying then usual and sometimes its simpler to just fallback into handling error conditions by returning null or an error code. 在异步代码中管理异常比平常更烦人,有时通过返回null或错误代码来回退到处理错误条件更简单。

Also, we made sure that any exceptions that we create ourselves are instances of the builtin Error class, intead of other objects. 此外,我们确保我们自己创建的任何异常都是内置Error类的实例,其他对象的内容。 The reason is that the builtin Error class records the line number and stack trace of where it was generated in a kind of cross-browser way. 原因是内置的Error类以一种跨浏览器的方式记录它的生成位置的行号和堆栈跟踪。

2016 solution 2016解决方案

If you're using native ES Promises do absolutely nothing; 如果你正在使用原生的ES Promises,那就什么都不做; Chrome automatically reports uncaught promise rejections in the console. Chrome会自动在控制台中报告未被捕获的拒绝承诺。

Chrome开发工具中的“Uncaught Promise错误”

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. 注意捕获的一个( Second fail )没有显示任何内容,但代码完成运行后控制台中出现未被捕获的拒绝。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM