1

参照されたライブラリによってスローされたすべての例外が自分のライブラリをエスケープしないようにしたいと考えています。私は、MyException型でない場合に例外をラップする try catch を介してすべての関数をフィルタリングすることによってこれを行っています。私が抱えている問題は、例外がMyExceptionタイプの場合、ラップ関数で、新しい場所から同じ例外を再スローし、最初にスローされた例外を埋め込まないため、元のスタック トレースが失われてしまうことです。スタック トレースは、例外が再スローされる新しい場所から記録されるため、元のスタック トレースthrowは失われます。

public static Exception Wrap(Exception exception)
{
    Exception exceptionToReturn;
    if (exception is MyException)
    {
        exceptionToReturn = exception;
    }
    else
    {
        exceptionToReturn = new MyException("Referenced library exception wrapped", exception);
    }

    return exception;
}

私がやろうとしているのはMyException、元のスタック トレースを保持するために派生したのと同じ種類の例外を再スローすることです。MyExceptionただし、次のようなコードですべての子をチェックしたくありません。

(exception is ChildOfMyException)
    exceptionToReturn = new ChildOfMyException(exception.Message, exception);

ジェネリックを使用する場合。明示的なコンストラクターを指定できません。

public static Exception Wrap<TException>(TException exception)
    where TException : Exception, new()
{
    Exception exc;
    if (exception is MyException)
    {
        exc = new TException();
    }
    else
    {
        exc = new MyException("Referenced library exception wrapped", exception);
    }
    return exc;
}

不足している方法がありますか、それともリフレクションを使用して _innerExceptionフィールドを変更する必要がありますか。

4

2 に答える 2

3

まず、例外を再スローする場合は、次を使用します。

throw;

そしてそうではない

throw ex;

最後のステートメントはスタック トレースを上書きし、最初のステートメントはそれを保持します。

キャッチブロック内でのみ例外を再スローできますが、別のメソッド内では再スローできません。次のようなことを試すことができます:

try
{
    // Any code
}
catch(MyException ex)
{
    throw;
}
catch(Exception ex)
{
    throw Wrap(ex);
}

Wrapメソッドがラップする必要がある例外のみをラップする場合。本質的には次のようになります。

try
{
    // Any code
}
catch(MyException ex)
{
    throw;
}
catch(Exception ex)
{
    throw new MyException("Referenced library exception wrapped", ex);
}

これがうまくいかない場合 (try-catch ブロックが何度も繰り返されるため)、それを行う可能性のある AOP を調べることもできます。Postsharp を使用すると、メソッドは次のようになります。

[ExceptionPolicy(bla bla)]
void MyMethod()
{
    // Any code
}

詳細については、http ://www.postsharp.net/ をご覧ください。

于 2013-06-17T06:06:25.973 に答える
0

元のスタック トレースを保存し、元の例外を再スローする場合は、throw代わりにthrow ex. したがって、ラップ関数は、スローまたは再スローを示すブール値と、新しい例外がある場合はその例外を返す必要があります。

このようなもの:

public static bool Wrap(ref Exception exception) {
    if (exception is MyException) {
        // false indicates a rethrow of the original exception
        return false;
    }
    exception = new MyException("Referenced library exception wrapped", exception);
    return true;
}

// Calling code
try {
    // Something
} catch (Exception ex) {
    if (SomeClass.Wrap(ref ex))
        throw ex;
    throw;
}
于 2013-06-17T06:09:27.763 に答える