2012-04-26 12 views
2

次のコードでは意図的にエラーをスローしますが、Chromeではテスト目的でのみ使用されますが、catchにはロールアップされません。親のスコープにエラーをロールアップするにはどうすればよいですか?JavaScriptエラーをロールバックするにはどうすればよいですか?

try { 
    setTimeout(function() { 
    console.log("Throwing Error..."); 
    throw({message:"Ouch!"}); 
    }, 500); 
} catch(e) { 
    console.log(e.message); 
} 

Chromeがで応答:ここ

Uncaught #<Object> 
    (anonymous function) 

は、私が働いている完全な例です。私が "ボブ"を必要とするとき、それは(意図的に)タイムアウトします。私はrequirejsエラーをキャッチしたいので、より堅牢な私のアプリケーションのエラーシステムを使用して、学習者に通知することができます。ブラウザがsetTimeoutコールバックを呼び出したときにあなたのthrow

(function() { 
try { 
    var scriptVersion = "1.0.0.1" 
    window.onload = function() { 
    var script = document.createElement("script"); 
    script.type = "text/javascript"; 
    script.src = "//content.com/pkg/" + scriptVersion + "/require-jquery.js"; 
    script.async = false; 
    script.done = false; 
    // OnReadyStateChange for older IE browsers 
    script.onload = script.onreadystatechange = function() { 
     if(!(this.done) && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) { 
     this.done = true; 
     require.config({ 
      baseUrl: "//content.com/pkg/" + scriptVersion 
     }); 
     require(["bob"]); 
     } 
    } 
    document.getElementsByTagName("head")[0].appendChild(script); 
    } 
} catch(e) { 
    console.log(e); 
} 
})(); 
+0

タイトル/説明にtry-catchとsetTimeoutを使用することをお勧めします。そうすれば、他の人が類似したものを探しているときに、彼らはあなたの質問と利益を見つけるかもしれません。 – pilavdzice

答えて

6

はrequireJSとの実際の問題を解決する方法については、以下の編集を参照してください。

問題は、setTimeout()関数が親スコープで実行され、エラーなしで完了することです。それは将来のコールバックイベントをスケジュールしますが、そのコールバックが将来発生すると、親の実行スコープは終了し、コールバックは新しいシステムイベントのようにトップレベルのシステムから開始されます(クリックイベントハンドラ)。

setTimeout()内の匿名関数がそれらの変数を引き続き参照できるため、親クロージャはまだ存在しますが、親スコープの実際の実行が行われ、try/catchのスコープが行われます。

setTimeout()匿名関数の実行コンテキストはトップレベル(システムによって開始される)なので、try/catchを入れることができる親コンテキストはありません。匿名関数内にtry/catchを入れることはできますがそこから投げることは、setTimeout()コールバックと呼ばれるシステムに戻るだけです。

setTimeout()コールバック内で発生する例外を独自のコードでキャッチするには、コールバック内にtry/catchを配置する必要があります。

setTimeout(function() { 
    try { 
     console.log("Throwing Error..."); 
     throw({message:"Ouch!"}); 
    } catch(e) { 
     console.log(e.message); 
    } 
    }, 500); 

あなたは本当の問題は、あなたが(むしろ、この製造テストケースよりも)解決しようとしていることが何であるかを説明している場合、我々はいくつかの便利なオプションを提供することができるかもしれません。


編集今、あなたはあなたが本当に解決しようとしている何の問題示したこと。 require.jsライブラリは、onErrorメソッドを呼び出してすべてのエラーを開始します。 onErrorメソッドのデフォルトの実装は、例外をスローします。独自のonErrorハンドラを割り当てて、例外ではなくコールバックでエラーを処理できます。これは正しい道に似ています。

requirejsソースから:

/** 
* Any errors that require explicitly generates will be passed to this 
* function. Intercept/override it if you want custom error handling. 
* @param {Error} err the error object. 
*/ 
req.onError = function (err) { 
    throw err; 
}; 
+0

「何かがうまくいかない場合は」キャッチが欲しかった。たとえば、requirejsを使用していますが、スクリプトの要求がタイムアウトするとエラーがスローされますが、アプリケーションのエラーをより適切にフォーマットするために、そのエラーを検出するのを見ました。 – scader

+0

質問を更新して完全なスクリプトを追加しました。ジェネリックテストケースで私に電話をしていただきありがとうございます。 – scader

+0

私はJavascriptが "すべてをキャッチ"しようとすると思います。システムから来るイベントや非同期コールバック(タイマーコールバック、Ajaxコールバックなど)は、それぞれを1つに入れない限り、try/catchブロックには本質的にありません。実際のコールバックを呼び出す前にtry/catchを実行したシェル関数をすべてのシステムコールバックまたはイベントハンドラが処理したが、独自のイベント処理やコールバックを行っているライブラリから保護することはできません取り扱い。 – jfriend00

1

は、catchブロックの後にいくつかの時間を発生します。

catchはレキシカルスコープを、論理的なスコープを使用していない)

+0

私はこのシナリオがうまくいくことを期待していたので、明らかに見逃してしまった。 – scader

1

以前の回答は、それを正しく説明しました。

別の考え方は、setTimeoutが正常終了し、最初に実行されたときに例外がスローされず例外が発生するためです。その後、try-catchブロック内にいなくなったときに実行されます。

それはあなたがこのようなsetTimeout関数の内部でトライキャッチを入れた場合に動作します:

setTimeout(function() { 
    try { 
     console.log("Throwing Error..."); 
     throw({message:"Ouch!"}); 
    } catch(e) { 
     console.log(e.message); 
    } 
     }, 500); 

あなたはまだ疑問を持っているなら、私に教えてください。

1

このようなラッパー機能を使用してください。

// wrapper function 
var tryable = function(closure, catchCallback) { 
    closure(function(callback) { 
     return function() { 
      try { 
       callback(); 
      } catch(e) { 
       catchCallback(e); 
      } 
     }; 
    }); 
}; 


function throwException() { 
    throw new Error("Hi"); 
} 
tryable(function(catchable) { 
    setTimeout(catchable(throwException), 1000); 
}, function(e) { 
    console.log("Error:)", e); 
}); 
関連する問題