5

これは悪い質問かもしれませんが、mootoolsを使用してコーディングを書いているときに、コールバック、バインディングを通過するコードがあり、一般的に単純な関数呼び出しではないことに気付きました。エラーはFirebugまたはChromeのコンソールのどちらにも検出されず、サイレントに失敗します。失敗しているコード行などの便利な情報が得られないように、trysなどを使用してエラーを追跡する必要があります。IE6のコードを書くようなものです。続けなければならないのは、「未定義の「x」を読み取れません」などの不透明なメッセージだけです。

質問は「これを回避するにはどうすればよいですか」という質問をするのに十分具体的ではないことを理解していますが、他の誰かがこの問題に遭遇しましたか?もしそうなら、どのように回避しますか?また、try / catchブロックでエラーを検出する方法についても少し混乱していますが、javascriptコンソールでは検出できません。

編集:

OK、エラーを再現するものを思いついた

あなたが機能を持っていると言う

function foo(){
   var x = value.blah;
}

その関数を呼び出すとfoo()、コンソールで参照エラーが発生します。しかし、私がそれを次のように呼ぶなら

(function(){
   foo.attempt();
})()

コンソールでエラーは発生しませんが、fooを次のように変更すると

function foo(){
   try{
   var x = value.blah;
   } catch(e){console.log(e)}
}

コンソールはeをログに記録しますが、もちろんハンドル'行:何でも'情報はありません。

4

1 に答える 1

8

JavaScriptのエラーをいじった経験はかなりあります。私は主に理解を深めるためにChromeを使用しましたが、そのほとんどはFirefoxとInternetExplorerにも当てはまります。

サイレントJavaScriptエラーについてのあなたの仮定をすぐに明らかにすることができます。それらは存在しません、エラーは常に表示されます。FirefoxまたはChromeのwebdevにバグがある可能性がありますが、エラーはあります。

エラーが表示されない最も一般的な方法は、自分でエラーをキャッチしているためです。おそらく時期尚早です。

エラーをキャッチするための最良の戦略は何だと思うかを理解しました。

Error1.常にsまたはsから継承されたものをスローしますError

例:ではない:throw "Precondition failed"しかしthrow new Error("Precondition failed")

これは、JavaScriptではエラーがおかしいためです(他に言葉はありません)。Errorスタックトレースが必要な場合(そして、天国の場合はスタックトレースが必要です)、 (文字列ではなく)をスローする必要があります。

2.window.onerrorを使用しないでください。ここで言うことはあまりありません。無駄だ。この関数に何を投げかけるかを制御することはできません。それはあなたのコードかもしれませんし、訪問者が使用する壊れたプラグインかもしれません。また、スタックトレースはありません。

3. 1つの(グローバル)エラーハンドラー/エラーをキャッチするタイミング

JavaScriptはイベント駆動型です。これはいくつかの予期しない結果をもたらします。次のコードを確認してください。

try {
    setTimeout(function () {
        throw new Error("nope! :D");
    }, 1);
} catch (e) {
    console.log(e);
}

このエラーは表示されません。(Firebug /コンソールはそれをキャッチしますが)

これは、内部関数がそれ自体のイベントで実行され、try-catchステートメントが適用されなくなったためです。正しい方法は次のとおりです。

try {
    setTimeout(function () {
        try {
            throw new Error("nope! :D");
        } catch (e) {
            console.log("Hell yea!", e);
        }
    }, 1);
} catch (e) {
    console.log(e);
}

または、関数をtry-catchでラップする関数を作成します。

function wrap(wrap_dat_func) {
    return function () {
        try {
            wrap_dat_func.apply(wrap_dat_func, arguments);
        } catch (e) {
            // send to error handler
        }
   }
}

次のように使用します:

setTimeout(wrap(function () {
    // etc
}), 1);

したがって、基本的に、新しいイベントを生成するときは常に、グローバルなtrycatch関数でコールバックをラップします。setTimeoutしたがって、への呼び出しをラップします。たとえば、AJAX呼び出しsetIntervalなどのすべてのDOM関連イベント。onclick onload ondocumentreadyonreadystatechanged

適切なスタックトレースを取得する方法(イベントを超えて!)は、もう1つの長い説明です。

于 2012-11-16T22:15:09.503 に答える