web-dev-qa-db-ja.com

内部例外をチェックする最良の方法は?

私は時々innerExceptionがnullであることを知っています

したがって、以下が失敗する可能性があります。

 repEvent.InnerException = ex.InnerException.Message; 

InnerExceptionがnullであるかどうかを確認する簡単な3つの方法はありますか?

55
JL.

これはあなたが探しているものですか?

String innerMessage = (ex.InnerException != null) 
                      ? ex.InnerException.Message
                      : "";
53
Andrew Hare

これまでの素晴らしい答え。似ているが異なるノートでは、ネストされた例外のレベルが複数ある場合があります。元々スローされたルート例外を取得したい場合は、どれだけ深くても、これを試してみてください。

public static class ExceptionExtensions
{
    public static Exception GetOriginalException(this Exception ex)
    {
        if (ex.InnerException == null) return ex;

        return ex.InnerException.GetOriginalException();
    }
}

そして使用中:

repEvent.InnerException = ex.GetOriginalException();
80
jrista

それは面白いです Exception.GetBaseException()

repEvent.InnerException = ex.GetBaseException().Message;
42
csharptest.net

最も簡単な解決策は、基本的な条件式を使用することです。

repEvent.InnerException = ex.InnerException == null ? 
    null : ex.InnerException.Message;
16
Noldorin

なぜこれらの答えにそんなに多くの再帰がありますか?

public static class ExceptionExtensions
{
    public static Exception GetOriginalException(this Exception ex)
    {
        while(ex.InnerException != null)ex = ex.InnerException;
        return ex;
    }
}

これを実装するはるかに簡単な方法のようです。

12
Yaur

その古い質問ですが、将来の読者のために:

既に投稿された答えに加えて、これを行う正しい方法は(複数のInnerExceptionを持つことができる場合)は Exception.GetBaseExceptionメソッド だと思います

例外インスタンスが必要な場合は、これを行う必要があります。

repEvent.InnerException = ex.GetBaseException();

この方法でのみメッセージを探している場合:

repEvent.InnerException = ex.GetBaseException().Message;
10
Diego

C#6.0では、次を使用できます。

string message = exception.InnerException?.Message ?? "";

このコード行は次のようになります。

string message = exception.InnerException == null ? "" : exception.InnerException.Message

https://msdn.Microsoft.com/en-us/library/ty67wk28.aspx

http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx

8
Toddams

C#6.0では、1行で実行できます。

repEvent.InnerException = ex.InnerException?.Message; 

c#6.0のその他の機能については、 こちら をクリックしてください

5
Ashwin

また、InnerExceptionにはInnerExceptionがある場合があるため、再帰関数を使用できます。

public string GetInnerException(Exception ex)
{
     if (ex.InnerException != null)
     {
        return string.Format("{0} > {1} ", ex.InnerException.Message, GetInnerException(ex.InnerException));
     }
   return string.Empty;
}
5
Jan Remunda

このコードを使用すると、内部例外メッセージが失われなかったことを確認できます。

catch (Exception exception)
{
   Logger.Error(exception.Message);
   while (exception.InnerException != null)
   {
       exception = exception.InnerException;
       Logger.Error(exception);
   }
}
2
neustart47

次に、メッセージとスタックトレースを追加して、それらを完全にする別の可能な実装を示します。

private static Tuple<string, string> GetFullExceptionMessageAndStackTrace(Exception exception)
{
    if (exception.InnerException == null)
    {
        if (exception.GetType() != typeof(ArgumentException))
        {
            return new Tuple<string, string>(exception.Message, exception.StackTrace);
        }
        string argumentName = ((ArgumentException)exception).ParamName;
        return new Tuple<string, string>(String.Format("{0} With null argument named '{1}'.", exception.Message, argumentName ), exception.StackTrace);
    }
    Tuple<string, string> innerExceptionInfo = GetFullExceptionMessageAndStackTrace(exception.InnerException);
    return new Tuple<string, string>(
    String.Format("{0}{1}{2}", innerExceptionInfo.Item1, Environment.NewLine, exception.Message),
    String.Format("{0}{1}{2}", innerExceptionInfo.Item2, Environment.NewLine, exception.StackTrace));
}


[Fact]
public void RecursiveExtractingOfExceptionInformationOk()
{
    // Arrange
    Exception executionException = null;
    var iExLevelTwo = new NullReferenceException("The test parameter is null");
    var iExLevelOne = new ArgumentException("Some test meesage", "myStringParamName", iExLevelTwo);
    var ex = new Exception("Some higher level message",iExLevelOne);

    // Act 
    var exMsgAndStackTrace = new Tuple<string, string>("none","none");
    try
    {
        exMsgAndStackTrace = GetFullExceptionMessageAndStackTrace(ex);
    }
    catch (Exception exception)
    {
        executionException = exception;
    }

    // Assert
    Assert.Null(executionException);

    Assert.True(exMsgAndStackTrace.Item1.Contains("The test parameter is null"));
    Assert.True(exMsgAndStackTrace.Item1.Contains("Some test meesage"));
    Assert.True(exMsgAndStackTrace.Item1.Contains("Some higher level message"));
    Assert.True(exMsgAndStackTrace.Item1.Contains("myStringParamName"));

    Assert.True(!string.IsNullOrEmpty(exMsgAndStackTrace.Item2));

    Console.WriteLine(exMsgAndStackTrace.Item1);
    Console.WriteLine(exMsgAndStackTrace.Item2);
}
1
Ognyan Dimitrov
class MyException : Exception
{
    private const string AMP = "\r\nInnerException: ";
    public override string Message
    {
        get
        {
            return this.InnerException != null ? base.Message + AMP + this.InnerException.Message : base.Message;
        }
    }

    public override string StackTrace
    {
        get
        {
            return this.InnerException != null ? base.StackTrace + AMP + this.InnerException.StackTrace : base.StackTrace;
        }
    }
}
1
qwert_ukg

はい:

if (ex.InnerException == null) {
    // then it's null
}
1
Dan Tao

例外フィルターを使用して、より正確な照準を得ることができます。

catch (Exception ex) when (ex.InnerException != null) {...}

詳細をご覧ください こちら

0
Valerii