質問

何のためのベストプラクティスに考慮すべきポイントについて例外を捕捉および再投げているのか。を確認して欲しいとの Exception オブジェクトの InnerException とスタックトレースが保存されます。間に差はあるには、次のコードブロックの立ち寄りください。

try
{
    //some code
}
catch (Exception ex)
{
    throw ex;
}

Vs:

try
{
    //some code
}
catch
{
    throw;
}
役に立ちましたか?

解決

の保存のスタックトレースの使用による throw; これは有効なも

try {
  // something that bombs here
} catch (Exception ex)
{
    throw;
}

throw ex; 基本的には様には、例外をスローからその点で、スタックトレースが行き場を発行 throw ex; ます。

マイク も正しいと仮定の例外では通例外をお勧めします。

Karl Seguinもの書きに例外処理 彼の 基盤プログラミングのe-book もし、これを読み込みます。

編集:労働へのリンク 基盤プログラミング pdfとしています。だけで、検索のための"例外".

他のヒント

ま捨てて新規例外は、初期の例外での保存、初期のスタックトレースあります。

try{
} 
catch(Exception ex){
     throw new MoreDescriptiveException("here is what was happening", ex);
}

実際には、状況もあるの throw statmentませんの保全にStackTraceます。例えば、以下のコード:

try
{
  int i = 0;
  int j = 12 / i; // Line 47
  int k = j + 1;
}
catch
{
  // do something
  // ...
  throw; // Line 54
}

のStackTraceすることを示す線54の例外では育てられた行47.

Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.
   at Program.WithThrowIncomplete() in Program.cs:line 54
   at Program.Main(String[] args) in Program.cs:line 106

そういうとき上記の通りオプションpreseveのStackTrace:

の呼び出します。InternalPreserveStackTrace

そのままに私の方法で呼び出される光:

private static void PreserveStackTrace(Exception exception)
{
  MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
    BindingFlags.Instance | BindingFlags.NonPublic);
  preserveStackTrace.Invoke(exception, null);
}

私の不利益に依存する民間の保のStackTraceます。変更することができ、将来のバージョンです。NET Framework.のコード例では、上記提案した以下の対策として、そこから抽出しました Fabrice MARGUERIEブログ.

呼び出します。SetObjectData

その技術を下したことを示唆する アントンTykhyy と答え クライアントまで、フルのC#できまrethrow InnerException失うことなくスタックトレース 質問です。

static void PreserveStackTrace (Exception e) 
{ 
  var ctx = new StreamingContext  (StreamingContextStates.CrossAppDomain) ; 
  var mgr = new ObjectManager     (null, ctx) ; 
  var si  = new SerializationInfo (e.GetType (), new FormatterConverter ()) ; 

  e.GetObjectData    (si, ctx)  ; 
  mgr.RegisterObject (e, 1, si) ; // prepare for SetObjectData 
  mgr.DoFixups       ()         ; // ObjectManager calls SetObjectData 

  // voila, e is unmodified save for _remoteStackTraceString 
} 

でその利点を頼りに公共の方法にもよりますが、以下の例外をコンストラクタ(一部例外が開発した3者が実装されません):

protected Exception(
    SerializationInfo info,
    StreamingContext context
)

私の状況をお選びいただける最初のアプローチの例外を上げる3-サードパーティ製ライブラリを使ったん実施このコンストラクタです。

throw ex, には、基本的に投入して新規例外、お見逃しのスタックトレース情報です。 throw の優先出方法。

の経験則ではなく、投基本 Exception オブジェクトです。この勢いでちょっときれいな色になくても例外つまりすべて明示的にキャッチボールa SqlException そのお取り扱いにコードがないように、 NullReferenceException.

現実の世界でもキャッチし、 およびログイン ベースの例外はも良い練習ができ、さも忘れては歩くのものを得 InnerExceptions れています。

誰も説明の違い ExceptionDispatchInfo.Capture( ex ).Throw() 平野 throw, なお久しぶりです、どらすこです。しかし一方で、知の問題 throw.

完全にrethrow aで獲れた例外は使用 ExceptionDispatchInfo.Capture( ex ).Throw() のみからご利用いただけます。純4.5).

以下の場合を試験する必要があるこ

1.

void CallingMethod()
{
    //try
    {
        throw new Exception( "TEST" );
    }
    //catch
    {
    //    throw;
    }
}

2.

void CallingMethod()
{
    try
    {
        throw new Exception( "TEST" );
    }
    catch( Exception ex )
    {
        ExceptionDispatchInfo.Capture( ex ).Throw();
        throw; // So the compiler doesn't complain about methods which don't either return or throw.
    }
}

3.

void CallingMethod()
{
    try
    {
        throw new Exception( "TEST" );
    }
    catch
    {
        throw;
    }
}

4.

void CallingMethod()
{
    try
    {
        throw new Exception( "TEST" );
    }
    catch( Exception ex )
    {
        throw new Exception( "RETHROW", ex );
    }
}

事例1事例2までのスタックトレースのソースコードの行番号を CallingMethod 方法は、 throw new Exception( "TEST" ) ます。

しかし、場合には3つまでスタックトレースのソースコードの行番号を CallingMethod 方法は、 throw ます。このことは、 throw new Exception( "TEST" ) 線に囲まれたその他の業務に使える行数は、例外が実際にスローされます。

事例4非常に優秀な方々と働くことがでケース2では、回線数の例外は、保存したものではありませんリアルrethrowでの変更のタイプの例外です。

少数の人々が実際に見ても重要なポイント-"捨"と"捨てると元の場合と同じことを行ないませんので、重要な文字である線の例外が起こりました。

以下のコードを考えてみます::

static void Main(string[] args)
{
    try
    {
        TestMe();
    }
    catch (Exception ex)
    {
        string ss = ex.ToString();
    }
}

static void TestMe()
{
    try
    {
        //here's some code that will generate an exception - line #17
    }
    catch (Exception ex)
    {
        //throw new ApplicationException(ex.ToString());
        throw ex; // line# 22
    }
}

いかに"捨てる"または"捨てると元のスタックトレースのインは#22はできませんギャラリーラインを正確にし、例外を投げしている場合を除く1または数行のコードは、tryブロック).の期待線#17日に例外だけに新しい例外の例外のスタックトレース.

しなければなりません利用で"投げる"rethrowの例外です。ネッ

参照、 http://weblogs.asp.net/bhouse/archive/2004/11/30/272297.aspx

基本的にはMSIL(CIL)は二つの方法-"投げる"、"rethrow":

  • C#'s"投ex;"がめMSILの"捨てる"
  • C#'s"投;"にMSIL"rethrow"!

基本的に見える理由は"投ex"オーバーライドのスタックトレース.

で入力することもできます:

try
{
// Dangerous code
}
finally
{
// clean up, or do nothing
}

他の例外がスローされますバブルのレベルを取り扱う。

この利用:

try
{
    //some code
}
catch
{
    //you should totally do something here, but feel free to rethrow
    //if you need to send the exception up the stack.
    throw;
}

うるおいを保ちスタックです。

ご参考までの試験はこのスタックトレースの報告による投;"ではない全く正しいスタックトレース.例:

    private void foo()
    {
        try
        {
            bar(3);
            bar(2);
            bar(1);
            bar(0);
        }
        catch(DivideByZeroException)
        {
            //log message and rethrow...
            throw;
        }
    }

    private void bar(int b)
    {
        int a = 1;
        int c = a/b;  // Generate divide by zero exception.
    }

のスタックトレースの原点であり、例外が正しく(行番号)が行番号の報告をしてfoo()のラインはその投;決ができないの電話を"マニュアル"連写スピードには例外です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top