12

Webアプリケーションのデバッグに問題があります。jsfiddleに投稿できる小さなWebページで問題を再現しようとしていたので、非常にイライラしますが、これは「Higgs-Bugson」の場合のようです。

jQuery(document).ready()大きなハンドラーを持つWebページがあります。問題は、ハンドラー内から例外がスローされるjQuery(document).ready()と、いくつかの無名関数を含む呼び出しスタックが取得され、実際に例外をスローしたコードへのポインターがないことです。

小さなWebページでこの動作を再現しようとすると、例外をスローしたコードへのポインターが常に取得されますが、本番コードでは、スタックポインターが取得されません。これにより、デバッグがより苛立たしくなり、エラーが発生しやすくなります。

ここにいる誰かが、この動作を引き起こしている可能性のあるものと、それを正しくする方法について何か考えがありますか?


更新:この質問を投稿してから数か月が経ちましたが、この問題を最終的に再現したと思います。次の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はエラーをキャッチし、エラーが発生したコード行を強調表示して、とを含む呼び出しスタックを表示しfactorialますbtnFactorial_click

factorial(-1)このコードは、$(document).readyハンドラーからも呼び出します。この場合、Visual Studioは、次のjQueryコード(987行目からjquery-1.6.1.jsから抜粋)のfinallyブロックにハイライトを移動します。

            // 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;
            },

呼び出しスタックは表示されませんが、VisualStudioはエラーのテキストを示すポップアップを表示します。

この奇妙な動作の理由は何ですか?また、$(document).readyなどのハンドラーから発生するエラーを簡単にトラップできるようにアプリケーションを設計するにはどうすればよいですか?

4

3 に答える 3

4

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/

jsfiddle を chrome で実行すると、factorial(-1) の最初の実行が呼び出されます。エラーが表示されます。右下の赤い x をクリックするか、要素を調べてコンソール タブに移動し、テキスト領域を見ることでアクセスできます。エラーは、「キャッチされていないエラー: 階乗関数は負の数をサポートしていません」と正しく表示され、使用されている正確な行へのリンクがありthrow new Error()ます。

もう少し説明が必要かもしれませんが、あなたが解決しようとしている問題は何ですか? クロムはこのスクリプトをうまくデバッグしているようです。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
于 2012-06-14T17:42:51.757 に答える
1

組み込みの IE デバッガーで小さな例を試してみたところ、例外メッセージが正常に報告され、カーソルがスローに置かれました。

クロムでも同じ。

私はjquery v1.6.2を持っています。多分アップグレードする価値がありますか?

繰り返しますが、これはスレッドの問題のようなにおいがします。UI の更新 (アラートなど) と共に常に発生する場合は、VS デバッガーが js スレッド内にあると認識しているときに、UI サーバー スレッドを参照している可能性があります。つまり、デバッガーのバグです。この場合は、別のデバッガーを試して、問題が解決するかどうかを確認してください

于 2012-08-10T04:35:26.377 に答える