예외에서 전체 스택 추적을 인쇄하는 방법은 무엇입니까?


98

예를 들어 한 곳에서 ...

//---------------a
try
{
    // some network call
}
catch(WebException we)
{
    throw new MyCustomException("some message ....", we);
}

... 그리고 다른 곳에서 ...

//--------------b
try
{
    // invoke code above
}
catch(MyCustomException we)
{
    Debug.Writeline(we.stacktrace);   // <----------------
}

내가 인쇄하는 stacktrace는 a에서 b까지만 시작하며 WebException의 내부 스택 추적을 포함하지 않습니다.

모든 스택 트레이스를 어떻게 인쇄 할 수 있습니까 ???


1
WebException을 다시 던지는 대신 새 예외를 던 졌으므로 원래 WebException에 대한 스택 추적이 인쇄되지 않습니다. 원래 예외 스택을 보존 (및 출력)하려는 경우 throw;대신 사용 throw new MyCustomException(...)합니다.
Beel

답변:


174

일반적으로 예외에 대해 .ToString () 메서드를 사용하여 전체 예외 정보 (내부 스택 추적 포함)를 텍스트로 표시합니다.

catch (MyCustomException ex)
{
    Debug.WriteLine(ex.ToString());
}

샘플 출력 :

ConsoleApplication1.MyCustomException: some message .... ---> System.Exception: Oh noes!
   at ConsoleApplication1.SomeObject.OtherMethod() in C:\ConsoleApplication1\SomeObject.cs:line 24
   at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 14
   --- End of inner exception stack trace ---
   at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 18
   at ConsoleApplication1.Program.DoSomething() in C:\ConsoleApplication1\Program.cs:line 23
   at ConsoleApplication1.Program.Main(String[] args) in C:\ConsoleApplication1\Program.cs:line 13

아주 좋아요. 나는 그것을 할 간단한 방법을 찾고 있었고 여기에 있습니다. 약간의 우려는 당신이 exception.StackTrace 객체를 사용하는 것만 큼 명시 적이 지 않다는 것입니다 (예를 들어). 동일한 작업을 수행하는 더 명확한 방법이 있는지 궁금합니다.
codea 2014 년

4
일부 라이브러리 ToString는 전체 정보 대신 메서드를 재정의하고 사용자 지정 메시지를 인쇄 한다는 점에 유의 하십시오 (이것은 나쁜 코딩 관행이므로 절대 그렇게 하지 마십시오)
Dinei

@P ரதீப் ToString덮어 쓰지 않았다고 확신 할 때마다 사용하고 그렇지 않으면 속성을 직접 사용합니다 ( Andrew Hare의 답변 처럼 ).
Dinei

53

다음과 같은 기능을 사용하십시오.

    public static string FlattenException(Exception exception)
    {
        var stringBuilder = new StringBuilder();

        while (exception != null)
        {
            stringBuilder.AppendLine(exception.Message);
            stringBuilder.AppendLine(exception.StackTrace);

            exception = exception.InnerException;
        }

        return stringBuilder.ToString();
    }

그런 다음 다음과 같이 부를 수 있습니다.

try
{
    // invoke code above
}
catch(MyCustomException we)
{
    Debug.Writeline(FlattenException(we));
}

13
아니면 사용할 수 ToString있습니까?
Justin

나는 ToString을 사용하고 있고 괜찮다고 생각합니다. 가장 낮은 내부 예외 (실제 이유 포함) 또는 유사한 선택 만 원하는 경우 Andrew의 솔루션으로 갈 것입니다. 둘 다 작동합니다. :)
EeKay

이 문자열에 들어가는 것을 선택할 수 있기 때문에 ToString보다 더 유연합니다. 아마도 메시지가 아닌 스택 추적에만 관심이있을 수 있습니다. 또는 단일 문자열이 아닌 List <string>으로 원합니다.
Zar Shardan

18

1. 메서드 생성 : 예외를 다음 함수에 전달하면 예외 원인 인 모든 메서드와 세부 정보가 제공됩니다.

public string GetAllFootprints(Exception x)
{
        var st = new StackTrace(x, true);
        var frames = st.GetFrames();
        var traceString = new StringBuilder();

        foreach (var frame in frames)
        {
            if (frame.GetFileLineNumber() < 1)
                continue;

            traceString.Append("File: " + frame.GetFileName());
            traceString.Append(", Method:" + frame.GetMethod().Name);
            traceString.Append(", LineNumber: " + frame.GetFileLineNumber());
            traceString.Append("  -->  ");
        }

        return traceString.ToString();
}

2. 호출 방법 : 다음 과 같이 호출 할 수 있습니다.

try
{
    // code part which you want to catch exception on it
}
catch(Exception ex)
{
    Debug.Writeline(GetAllFootprints(ex));
}

3. 결과 얻기 :

File: c:\MyProject\Program.cs, Method:MyFunction, LineNumber: 29  -->  
File: c:\MyProject\Program.cs, Method:Main, LineNumber: 16  --> 

1
매우 도움이됩니다. 귀하의 예를 기반으로 확장 방법을 만들었습니다 . BTW, 많은 반복의 경우 StringBuilder클래스를 사용하는 것이 좋습니다 .
AlexMelw

2
Andreys 링크가 죽었습니다. 이것이 그의 구현에 대한 현재 링크입니다. github.com/AndreyWD/EasySharp/blob/master/NHelpers/…
Christian Junk

전문적인 안드레이처럼 보입니다. 내 도구 상자에 라이브러리를 넣었습니다. 감사. @AndreyWD
Oguzhan KIRCALI
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.