代码之家  ›  专栏  ›  技术社区  ›  JL. Hans Passant

检查内部异常的最佳方法?

  •  52
  • JL. Hans Passant  · 技术社区  · 15 年前

    我知道有时候感觉是空的

    因此,以下内容可能会失败:

     repEvent.InnerException = ex.InnerException.Message; 
    

    是否有快速三元方法检查InnerException是否为空?

    14 回复  |  直到 6 年前
        1
  •  52
  •   Andrew Hare    15 年前

    这就是你要找的吗?

    String innerMessage = (ex.InnerException != null) 
                          ? ex.InnerException.Message
                          : "";
    
        2
  •  77
  •   jrista    15 年前

    到目前为止答案很好。在类似但不同的注释中,有时会有多个级别的嵌套异常。如果您想要获得最初抛出的根异常,不管有多深,您都可以尝试这样做:

    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();
    
        3
  •  39
  •   csharptest.net    15 年前

    很有趣,我找不到任何问题 Exception.GetBaseException() ?

    repEvent.InnerException = ex.GetBaseException().Message;
    
        4
  •  16
  •   Noldorin    15 年前

    最简单的解决方案是使用基本条件表达式:

    repEvent.InnerException = ex.InnerException == null ? 
        null : ex.InnerException.Message;
    
        5
  •  11
  •   Yaur    11 年前

    为什么在这些答案中有这么多递归?

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

    似乎是实现这一点的更直接的方法。

        6
  •  10
  •   Diego    11 年前

    这是一个古老的问题,但对于未来的读者来说:

    除了已经发布的答案之外,我认为正确的方法(当您可以有多个innerException时)是 Exception.GetBaseException Method

    如果需要异常实例,则应执行以下操作:

    repEvent.InnerException = ex.GetBaseException();
    

    如果您只是这样查找消息:

    repEvent.InnerException = ex.GetBaseException().Message;
    
        7
  •  8
  •   Toddams    9 年前

    使用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
  •  5
  •   Jan Remunda    15 年前

    有时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;
    }
    
        9
  •  4
  •   Ashwin    7 年前

    使用C 6.0,您可以在一行中完成它。

    repEvent.InnerException = ex.InnerException?.Message; 
    

    有关C 6.0的其他功能,请单击 here

        10
  •  1
  •   Dan Tao    15 年前

    对:

    if (ex.InnerException == null) {
        // then it's null
    }
    
        11
  •  1
  •   Ognyan Dimitrov    10 年前

    下面是另一个可能的实现,它附加了消息和堆栈跟踪,以便我们得到完整的消息和堆栈跟踪:

    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);
    }
    
        12
  •  1
  •   qwert_ukg    8 年前
    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;
            }
        }
    }
    
        13
  •  1
  •   kkost    8 年前

    使用此代码,您将确保不会丢失任何内部异常消息。

    catch (Exception exception)
    {
       Logger.Error(exception.Message);
       while (exception.InnerException != null)
       {
           exception = exception.InnerException;
           Logger.Error(exception);
       }
    }
    
        14
  •  0
  •   Val    6 年前

    可以使用异常过滤器来获得更精确的瞄准。

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

    请查找更多详细信息 here