IT TIP

내부 예외를 확인하는 가장 좋은 방법은 무엇입니까?

itqueen 2020. 12. 31. 23:15
반응형

내부 예외를 확인하는 가장 좋은 방법은 무엇입니까?


가끔 innerException이 null이라는 것을 알고 있습니다.

따라서 다음이 실패 할 수 있습니다.

 repEvent.InnerException = ex.InnerException.Message; 

innerException이 null인지 여부를 확인하는 빠른 삼항 방법이 있습니까?


이것이 당신이 찾고있는 것입니까?

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

지금까지 훌륭한 답변입니다. 비슷하지만 다른 메모에서 때로는 중첩 된 예외 수준이 두 개 이상입니다. 원래 던진 루트 예외를 얻으려면 아무리 깊이 있더라도 다음을 시도해 볼 수 있습니다.

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();

재미 있네요. Exception.GetBaseException ()에서 잘못된 것을 찾을 수 없습니까?

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

가장 간단한 해결책은 기본 조건식을 사용하는 것입니다.

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

이 답변에서 왜 그렇게 많은 재귀가 있습니까?

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

이것을 구현하는 훨씬 더 직접적인 방법 인 것 같습니다.


오래된 질문이지만 미래의 독자를 위해 :

이미 게시 된 답변 외에도이 작업을 수행하는 올바른 방법 (하나 이상의 InnerException을 가질 수있는 경우)은 Exception.GetBaseException 메서드 라고 생각합니다.

예외 인스턴스를 원하는 경우 다음을 수행해야합니다.

repEvent.InnerException = ex.GetBaseException();

이 방법으로 만 메시지를 찾는 경우 :

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

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


때로는 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;
}

C # 6.0에서는 한 줄로 할 수 있습니다.

repEvent.InnerException = ex.InnerException?.Message; 

C # 6.0의 다른 기능을 보려면 여기를 클릭 하십시오.


이 코드를 사용하면 내부 예외 메시지가 손실되지 않았 음을 확인할 수 있습니다.

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

예:

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

다음은 메시지와 스택 추적을 추가하는 또 다른 가능한 구현입니다.

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);
}

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;
        }
    }
}

보다 정확한 조준을 위해 예외 필터를 사용할 수 있습니다.

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

여기에서 자세한 내용을 확인 하십시오

참조 URL : https://stackoverflow.com/questions/1456563/best-way-to-check-for-inner-exception

반응형