Best way to check for inner exception?

后端 未结 14 2257
说谎
说谎 2020-12-02 11:57

I know sometimes innerException is null

So the following might fail:

 repEvent.InnerException = ex.InnerException.Message; 

Is ther

相关标签:
14条回答
  • 2020-12-02 12:25

    Its an old question but for future readers:

    In addition to the answers already posted I think the correct way to do this (when you can have more than one InnerException) is Exception.GetBaseException Method

    If you want the exception instance you should do this:

    repEvent.InnerException = ex.GetBaseException();
    

    If you are only looking for the message this way:

    repEvent.InnerException = ex.GetBaseException().Message;
    
    0 讨论(0)
  • 2020-12-02 12:26

    The simplest solution is to use a basic conditional expression:

    repEvent.InnerException = ex.InnerException == null ? 
        null : ex.InnerException.Message;
    
    0 讨论(0)
  • 2020-12-02 12:27

    Here is another possible implementation that appends the messages and stack traces so we get them full:

    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);
    }
    
    0 讨论(0)
  • 2020-12-02 12:28

    Great answers so far. On a similar, but different note, sometimes there is more than one level of nested exceptions. If you want to get the root exception that was originally thrown, no matter how deep, you might try this:

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

    And in use:

    repEvent.InnerException = ex.GetOriginalException();
    
    0 讨论(0)
  • 2020-12-02 12:28

    Sometimes also InnerException has an InnerException, so you can use a recursive function for it:

    public string GetInnerException(Exception ex)
    {
         if (ex.InnerException != null)
         {
            return string.Format("{0} > {1} ", ex.InnerException.Message, GetInnerException(ex.InnerException));
         }
       return string.Empty;
    }
    
    0 讨论(0)
  • 2020-12-02 12:30

    It is possible to use an exception filter to get more precise aiming.

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

    Please find more details here

    0 讨论(0)
提交回复
热议问题