2012-07-31 8 views
8

エラー報告のために、私が持っているすべての関数のコードの周りにtry-catchラッパーを挿入したいと思います。Javascriptのすべての関数にtry-catchを追加する方法はありますか?

だから、基本的に、私は...

function foo(arg){ 
    try { 
     bar() 
    } 
    catch(e){ 
     customErrorHandler(e) 
    } 
} 

で...

function foo(arg){ 
    bar(); 
} 

を交換したいすべて手動で編集せずに、すべての機能に、この一般的なのtry-catchのものを適用する方法はありますそのうちの?例えば、Functionオブジェクトのプロトタイプを変更することによって?

私はすべての機能キャッチを試みたいと思うのはなぜEDIT: は、私はiOSとAndroidの上で公開していますHTML5アプリを構築しています。私は私の現在の初歩的なjavascriptエラーから、アプリが自分のデバイス上でうまく動作しても、他のいくつかのデバイスでエラーが発生することを報告することができます。

私の目的は二つある:javascriptのエラーが誰かのデバイス上で発生するたびに...

  1. 私はアプリは完全に
  2. 私は大体どこエラー知りたい機能しないことがユーザに通知したいです発生したので、私は、私はここでそれを発見したように見える、
+1

いいえ - 実際にtry-catchを含んでいない場合は、関数の*呼び出し*をtry-catchで単にラップできますが、その内容にはラップできません。それが価値あるものであれば、try-catchステートメントでコードを覆うことはかなり悪い考えです。エラーがある場合は、解決する必要がありますが、try-catchで抑止する必要があります。 – Utkanos

+2

+1すべての機能を正しくキャッチしようとしています。しかし、あなたは手動でそれらをすべて編集しなければならないと思います。 – Limey

+1

トライキャッチは非常に高価です。これをやりたいですか?要件は何ですか? –

答えて

9

どこでも定義されているJavaScript関数をすべて見つける方法がないため、これは単純ではありません。例えば、そのようなアプローチは、おそらく実行時に定義されるコールバック関数を失います。

また、おそらくラップしたくないJavaScriptライブラリのブラウザ関数と関数が含まれているため、すべての関数をラップしたくない場合もあります。

var tcWrapper = function(f) { 
    return function() { 
     try { 
      f.apply(this, arguments); 
     } catch(e) { 
      customErrorHandler(e) 
     } 
    } 
} 

今、あなたはあなたが欲しいものを飾るために、この機能を使用することができます。

より良いアプローチは、別の関数をラップ関数を定義することが考えられます。あなたが名前空間を使用している場合ラッピングはよりシンプルになります:

var NS = { f: function(...) { ... } } 

だけの特別な名前空間にラップするすべての機能を配置し、名前空間を反復:

$.each(NS, function(i,n) { 
    var p = NS[n]; 
    if(typeof p === 'function') { 
     NS[n] = tcWrapper(p); 
    } 
}); 
+0

すべての機能が同じ「this」を必要とするわけではありません。たとえば、イベントハンドラがイベントターゲットまたはオブジェクトメソッドを取得することがあります。ただし、オブジェクトプロパティをループして、インライン関数でラップするgetter(Object.defineProperty)で置き換えることができます。インライン関数では、外部から改ざんできない値にラップするだけでなく、ラップそれらはtry catchブロック内にあります。 – nus

+0

@nus:私はあなたの意見は表示されません。私はちょうど 'this'を渡しますが、多分私は間違っていますか?たぶんあなたの情報は、コメントのためには複雑すぎます。コードとその理由を別の答えに示すのはどうですか? –

+0

申し訳ありませんが、返された関数が既にNSにアタッチされている場合にのみ、適用が実行されるのを見て間違いました。私は何とかtcpWrapperのコンテキストで呼び出されていると思っていました。この場合、すべての関数のtcpWrapperから 'this'が固定されていました。 – nus

1

オーケー問題のために場所を探すために知っている:http://www.nczonline.net/blog/2009/04/28/javascript-error-handling-anti-pattern/基本的に

、すべての関数は、try部分の元の関数を持つtry-catchラッパーに置き換えられます。

+6

ブログ記事のタイトルは、それが反パターンであると言います。つまり可能ですがお勧めできません。あなた次第ですが、私は本当にこれが良いアイデアだとは思いません。 – Utkanos

+1

ブログの記事では、アンチパターンについて説明していますが、解決策も示しています。 –

-3

私はあなたがこのような何かを行うことができます(これは、これがうまくいくかどうかわから純粋な憶測で、そうではない)だろ:

function callTryCatch(functionSignature) { 
    try { 
     eval(functionSignature); 
    } catch (e) { 
     customErrorHandler(e); 
    } 
} 

function entryPoint() { 
    callTryCatch(function() { 
     // do function logic 
    }); 
} 

繰り返しますが、これは純粋な憶測であり、私がテストしていないが、それもだ場合可能性私はキーがevalステートメントにあると思う。

+3

'eval'を使わないでください。あなたの場合、 'apply()'はあなたが望むことをします。 –

0

私はいくつかのコードを強化行くために必要な、そこで私はfortifyという関数を書いてNPMモジュールに入れました。進行中の作業ですが、役立つはずです。

https://github.com/infinitered/over-armour

ボーナス:それは非同期機能で動作します。フィードバックwelcome