İstisnai durumda tam yığın izleme nasıl yazdırılır?


98

Örneğin, tek bir yerde ...

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

... ve başka bir yerde ...

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

Yazdırdığım yığın izleme, yalnızca a'dan b'ye başlıyor, WebException'dan iç yığın izini içermiyor.

Tüm yığın izini nasıl yazdırabilirim ???


1
WebException'ı yeniden atmak yerine yeni bir özel durum oluşturduğunuz için, ortaya çıkan WebException için yığın izlemenin yazdırılmayacağını unutmayın. Orijinal istisna yığınını korumak (ve çıktı almak) istiyorsanız bunun throw;yerine kullanın throw new MyCustomException(...).
Beel

Yanıtlar:


177

Metinde tam istisna bilgilerini (iç yığın izleme dahil) sunmak için genellikle .ToString () yöntemini istisnalarda kullanıyorum:

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

Örnek çıktı:

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

Çok iyi. Bunu yapmanın basit bir yolunu arıyordum ve işte burada. Bazı küçük endişeler, istisna.StackTrace nesnesini kullanıyormuşsunuz gibi açık olmamasıdır (örneğin). Acaba aynısını yapmanın daha açık bir yolu var mı?
codea

4
Bazı kitaplıkların ToStringyöntemi geçersiz kıldığını ve tüm bilgiler yerine özel mesajlar yazdırdığını unutmayın (bu kötü bir kodlama uygulamasıdır, bu yüzden bunu asla yapmayın)
Dinei

@P ரதீப் Üzerine yazılmadığından ToStringemin olduğum her zaman kullanıyorum ve özellikleri doğrudan başka türlü kullanıyorum ( Andrew Hare'in cevabı gibi ).
Dinei

53

Bunun gibi bir işlev kullanın:

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

O zaman şöyle diyebilirsiniz:

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

15
Ya da kullanabilir ToStringmisin?
Justin

ToString kullanıyorum ve iyi olduğunu düşünüyorum. Yalnızca en düşük iç istisnayı (asıl nedenden dolayı) veya benzer bir seçim yapmak istiyorsam, Andrew'un çözümüyle giderdim .. her ikisi de işe yarıyor :)
EeKay

Bu, yalnızca ToString'den daha esnektir, çünkü bu dizeye neyin gireceğini seçebilirsiniz. Belki mesajlarla değil, yalnızca yığın izleriyle ilgileniyorum. Ya da tek bir dize değil List <string> olmasını istiyorum.
Zar Shardan

Ya iç istisnalar?
Clark

18

1. Yöntem Oluştur: Aşağıdaki işleve istisnanızı iletirseniz, istisnanın nedenleri olan tüm yöntemleri ve ayrıntıları size verecektir.

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. Çağrı Yöntemi: Yöntemi bu şekilde çağırabilirsiniz.

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

3. Sonucu Alın:

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

1
Oldukça faydalı. Örneğinize göre bir uzatma yöntemi yaptım . BTW, çok sayıda yineleme olması durumunda, StringBuildersınıfı kullanmanız daha iyi olur .
AlexMelw

2
Andreys bağlantısı kesildi. Bu, uygulamasına giden mevcut bağlantıdır: github.com/AndreyWD/EasySharp/blob/master/NHelpers/…
Christian Junk

Bu profesyonel görünüyor Andrey. Kitaplığınızı alet kutuma koydum. Teşekkürler. @AndreyWD
Oğuzhan KIRCALI
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.