jquery - 当 jQuery 处理程序中抛出异常时,调用堆栈会丢失

标签 jquery debugging exception callstack

我在调试 Web 应用程序时遇到问题。这非常令人沮丧,因为我一直在尝试用一个可以发布在 jsfiddle 上的小网页来重现该问题,但这似乎是“Higgs-Bugson”的情况。

我有一个带有大型 jQuery(document).ready() 处理程序的网页。问题是,当从 jQuery(document).ready() 处理程序中引发异常时,我得到一个包含多个匿名函数的调用堆栈,并且没有指向实际引发异常的代码的指针.

每当我尝试使用小网页重现此行为时,我总是得到一个指向引发异常的代码的指针,但在生产代码中,我从来没有获取堆栈指针。这使得调试更加令人沮丧并且容易出错。

这里有人知道可能导致这种行为的原因以及如何纠正吗?

<小时/>

更新:自从我发布这个问题以来已经过去了几个月,我现在相信我已经最终重现了这个问题。我使用以下 HTML 重现了该问题:

<html xmlns="http://www.w3.org/1999/xhtml" >    
<body>
Factorial Page
<input type='button' value='Factorial' id='btnFactorial' />
<script src="Scripts/jquery-1.6.1.js" type="text/javascript"></script>
<script type='text/javascript'>
    $(document).ready(documentReady);

    function documentReady() {
        $('#btnFactorial').click(btnFactorial_click);

        factorial(-1);
    }

    function btnFactorial_click() {
        var x;
        x = prompt('Enter a number to compute factorial for.', '');
        alert(x + '! = ' + factorial(x));
    }

    function factorial(x) {
        if (x < 0)
            throw new Error('factorial function doesn\'t support negative numbers');
        else if (x === 0 || x === 1)
            return 1;
        else
            return factorial(x - 1) * x;
    }
</script>       
</body>
</html>

查看代码,您会发现当您单击按钮时,代码会提醒您指定的数字的阶乘。输入负数将会产生错误。在这种情况下,Visual Studio 将捕获错误并突出显示发生错误的代码行,并显示包括 factorialbtnFactorial_click 的调用堆栈。

此代码还从 $(document).ready 处理程序调用 factorial(-1)。在本例中,Visual Studio 将突出显示移动到以下 jQuery 代码中的 finally block (摘自 jquery-1.6.1.js,从第 987 行开始

            // resolve with given context and args
            resolveWith: function( context, args ) {
                if ( !cancelled && !fired && !firing ) {
                    // make sure args are available (#8421)
                    args = args || [];
                    firing = 1;
                    try {
                        while( callbacks[ 0 ] ) {
                            callbacks.shift().apply( context, args );
                        }
                    }
                    finally {
                        fired = [ context, args ];
                        firing = 0;
                    }
                }
                return this;
            },

虽然未显示调用堆栈,但 Visual Studio 会显示一个弹出窗口,其中显示错误文本。

这种奇怪行为的原因是什么?如何设计我的应用程序,以便可以轻松捕获源自 $(document).ready 等处理程序的错误?

最佳答案

I'm having a problem debugging my web applications

您使用什么类型的调试器?它们往往各不相同,我在开发时发现最好的一个是 Firefox,因为它们拥有一些非常好的集成工具。

虽然重现问题很好,但当无法在简单简洁的示例中重现问题时,调试就变得越来越重要。设置断点并逐行运行有时是唯一的方法,而不是等待运行时发生错误然后回溯。

这篇 MSDN 文章中概述了几种可能有助于解决您的问题的方法。我确信您已经尝试过其中的一些,但它至少值得一看 - 特别是“场景 3:我在一组辅助方法的深处遇到错误,并且我不确定错误源自何处。”

“如何调试 jQuery 代码”

http://msdn.microsoft.com/en-us/magazine/ee819093.aspx

根据新内容进行编辑

jsfiddle新内容:http://jsfiddle.net/EJbsS/

在 chrome 中运行 jsfiddle 时,会调用第一次运行 Factorial(-1) 。出现错误。可以通过单击右下角的红色 x 来访问它,或者通过检查元素、导航到控制台选项卡,然后查看文本区域来访问它。该错误正确地显示为“未捕获错误:阶乘函数不支持负数”,并链接到 throw new Error() 所在的确切行。已使用。

也许我需要更多说明,您想要解决的问题是什么?看来 chrome 调试这个脚本就好了。也许 Visual Studio 的调试器存在一些问题。

此外

这是一个工作页面的复制品,可以从记事本中使用,另存为 .html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>demo</title> 
<script type='text/javascript' src='http://code.jquery.com/jquery-1.6.4.js'></script>
<script type='text/javascript'>//<![CDATA[ 
$(window).load(function(){
$(document).ready(documentReady);
function documentReady() {
    $('#btnFactorial').click(btnFactorial_click);

    factorial(-1);
}

function btnFactorial_click() {
    var x;
    x = prompt('Enter a number to compute factorial for.', '');
    alert(x + '! = ' + factorial(x));
}

function factorial(x) {
    if (x < 0)
        throw new Error('factorial function doesn\'t support negative numbers');
    else if (x === 0 || x === 1)
        return 1;
    else
        return factorial(x - 1) * x;
}
});//]]>  
</script>
</head>
<body>
Factorial Page
<input type='button' value='Factorial' id='btnFactorial' />  
</body>
</html>

在 google chrome 中运行此页面时,导航到“源”选项卡,并在 Line 26: if (x < 0) 设置断点当页面运行时,整个调用堆栈将在右侧重现。

factorial (debugpage.html:26)
documentReady (debugpage.html:16)
jQuery.extend._Deferred.deferred.resolveWith (jquery-1.6.4.js:1016)
jQuery.extend._Deferred.deferred.done (jquery-1.6.4.js:1002)
jQuery.fn.jQuery.ready (jquery-1.6.4.js:282)
(anonymous function) (debugpage.html:11)
jQuery.event.handle (jquery-1.6.4.js:3001)
jQuery.event.add.elemData.handle.eventHandle (jquery-1.6.4.js:2635)

更进一步

希望这个警告是迄今为止最好的。稍微研究一下堆栈跟踪,我发现了这个:console.trace(); 。它非常有用。

将其插入到上面代码的第 26 行,如下所示:

if (x < 0)
    throw new Error('factorial function doesn\'t support negative numbers');
else if (x === 0 || x === 1)

成为

if (x < 0){
    console.trace();
    throw new Error('factorial function doesn\'t support negative numbers');
}else if (x === 0 || x === 1)

现在运行它,没有断点,将在满足错误条件时在控制台中生成堆栈跟踪:

console.trace() debugpage.html:27
factorial debugpage.html:27
documentReady debugpage.html:16
jQuery.extend._Deferred.deferred.resolveWith jquery-1.6.4.js:1016
jQuery.extend._Deferred.deferred.done jquery-1.6.4.js:1002
jQuery.fn.jQuery.ready jquery-1.6.4.js:282
(anonymous function) debugpage.html:11
jQuery.event.handle jquery-1.6.4.js:3001
jQuery.event.add.elemData.handle.eventHandle

关于jquery - 当 jQuery 处理程序中抛出异常时,调用堆栈会丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10501069/

相关文章:

jquery - 图像是固定的,其他是相对的

javascript - 动态更改工具提示文本 (tippy.js)

javascript - 如何在 asp.net 中调试 javascript?

c++ - 如何不为特定源文件/源部分生成调试信息?

java - 如何将 messages.properties 键发送到 Controller 中引发的异常?

javascript - JQuery 使用 $.ajax() 访问远程站点

javascript - 发送新消息时向下滚动到底部

visual-studio - 禁用 VS' "downloading public symbols"

C# 显示 Oracle 过程中的自定义错误

exception - mips异常处理beq无法正常工作