İstisna atanan satır numarasını nasıl alabilirim?


198

Bir catchblokta, istisna atan satır numarasını nasıl alabilirim?


çalışma zamanında kaynak kodu yoktur. Bu satır no ne için kullanılacak? hata ayıklama zamanında, IDE açıkça istisna atan satırı gösterir.
ankitjaininfo



@ankitjaininfo IDE yoksa yararlı değil !
Michael

Bu sorunuza cevap veriyor mu? İstisna işlemede satır numarasını göster
Liam

Yanıtlar:


281

Satır numarasına Exception.StackTrace'ten aldığınız biçimlendirilmiş yığın izlemesinden daha fazlası için ihtiyacınız varsa, StackTrace sınıfını kullanabilirsiniz :

try
{
    throw new Exception();
}
catch (Exception ex)
{
    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}

Bunun yalnızca montaj için bir pdb dosyası varsa işe yarayacağını unutmayın.


2
? (Yeni StackTrace (ex, True)) .Girilen pencereden VB tek satır için GetFrame (0) .GetFileLineNumber ().
Jonathan

34
C # bir astar:int line = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
gunwin

17
Bu benim için her zaman 0 döndürür. Bu bir pdb dosyası olmamasından kaynaklanıyor mu? Nedir ve nasıl alınır? (ASP.net kullanıyorum)
Brabbeldas

17
Neden GetFrame (0) kullanıyorsunuz? GetFrame (FrameCount-1) kullanıyor olmanız gerektiğini düşünürdüm.
Dewald Swanepoel

9
Ben @DewaldSwanepoel GetFrame(st.FrameCount-1)çok daha güvenilir olmak için kullanarak öneri bulundu .
Brad Martin

75

Basit bir şekilde, Exception.ToString()işlevi kullanın , istisna açıklamasından sonra satırı döndürecektir.

Ayrıca tüm uygulama hakkında hata ayıklama bilgileri / günlükleri içerdiğinden program hata ayıklama veritabanını da kontrol edebilirsiniz.


Peki MSDN farklı düşünüyor, "Geçerli istisnanın dize temsilini oluşturur ve döndürür": msdn.microsoft.com/en-us/library/…
Prokurors

System.Exception: Test at Tests.Controllers.HomeController.About() in c:\Users\MatthewB\Documents\Visual Studio 2013\Projects\Tests\Tests\Controllers\HomeController.cs:line 22
programlama profesörü

3
Bu kabul edilen cevap olmalı. Her zaman ex.message için gitti ve aptal VB.net neden Java ile aynı bilgileri elde edemedi merak etti.
Matthis Kohli

3
Bu cevabın daha fazla oyu olmaması delilik. Bu basittir, güvenilir bir şekilde çalışır ve PDB uyarıları ile birlikte gelmez.
Nick Painter

9
Exception.Messagebenim için öldü. Bir daha asla.
Monica Cellio

27

.PBODosyanız yoksa :

C #

public int GetLineNumber(Exception ex)
{
    var lineNumber = 0;
    const string lineSearch = ":line ";
    var index = ex.StackTrace.LastIndexOf(lineSearch);
    if (index != -1)
    {
        var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
        if (int.TryParse(lineNumberText, out lineNumber))
        {
        }
    }
    return lineNumber;
}

Vb.net

Public Function GetLineNumber(ByVal ex As Exception)
    Dim lineNumber As Int32 = 0
    Const lineSearch As String = ":line "
    Dim index = ex.StackTrace.LastIndexOf(lineSearch)
    If index <> -1 Then
        Dim lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length)
        If Int32.TryParse(lineNumberText, lineNumber) Then
        End If
    End If
    Return lineNumber
End Function

Veya İstisna sınıfının bir uzantısı olarak

public static class MyExtensions
{
    public static int LineNumber(this Exception ex)
    {
        var lineNumber = 0;
        const string lineSearch = ":line ";
        var index = ex.StackTrace.LastIndexOf(lineSearch);
        if (index != -1)
        {
            var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
            if (int.TryParse(lineNumberText, out lineNumber))
            {
            }
        }
        return lineNumber;
    }
}   

8
Ne yazık ki ingilizce işletim sisteminde çalışmaz ("satır" kelime yerel ayarlara bağlıdır).
Ivan Kochurkin

2
@KvanTTT Şunları kullanabilirsiniz Regex.Matchile :[^ ]+ (\d+)aynı etki için.
Dan Bechard

Bu cevap benim için işe yaramaz, çünkü ex.StackTrace hiçbir şeye sahip değildir :line ve PDB dosyası yok.
Warlike Chimpanzee

18

Sen içerebilir .PDBmeta bilgileri içerir ve bir özel durum olduğunda bu istisna kökenli nerede stacktrace tam bilgileri içerir montaja ilişkili simge dosyalarını. Yığındaki her yöntemin satır numaralarını içerecektir.


Bir PDB dahil etmek nasıl olur? PDB'yi uygulamanın içine paketlemenin / GAC'ye kaydetmenin bir yolu var mı?
Jacob Persi


6

Bunu kontrol et

StackTrace st = new StackTrace(ex, true);
//Get the first stack frame
StackFrame frame = st.GetFrame(0);

//Get the file name
string fileName = frame.GetFileName();

//Get the method name
string methodName = frame.GetMethod().Name;

//Get the line number from the stack frame
int line = frame.GetFileLineNumber();

//Get the column number
int col = frame.GetFileColumnNumber();

1

Cevaba güncelleme

    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(st.FrameCount-1);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();

1

By @ davy-c çözümünü kullanmayı denedim ama "System.FormatException: 'Giriş dizesi doğru biçimde değildi." Bir istisnası vardı. yayınladı ve ile geldi:

int line = Convert.ToInt32(objErr.ToString().Substring(objErr.ToString().IndexOf("line")).Substring(0, objErr.ToString().Substring(objErr.ToString().IndexOf("line")).ToString().IndexOf("\r\n")).Replace("line ", ""));

Bu VS2017 C # benim için çalışıyor.


0

Genişletme Yöntemi

static class ExceptionHelpers
{
    public static int LineNumber(this Exception ex)
    {
        int n;
        int i = ex.StackTrace.LastIndexOf(" ");
        if (i > -1)
        {
            string s = ex.StackTrace.Substring(i + 1);
            if (int.TryParse(s, out n))
                return n;
        }
        return -1;
    }
}

kullanım

try
{
    throw new Exception("A new error happened");
}
catch (Exception ex)
{
    //If error in exception LineNumber() will be -1
    System.Diagnostics.Debug.WriteLine("[" + ex.LineNumber() + "] " + ex.Message);
}

0

Benim için çalışmak:

var st = new StackTrace(e, true);

// Get the bottom stack frame
var frame = st.GetFrame(st.FrameCount - 1);
// Get the line number from the stack frame
var line = frame.GetFileLineNumber();
var method = frame.GetMethod().ReflectedType.FullName;
var path = frame.GetFileName();

0

Satır, sütun, yöntem, dosya adı ve iletiyi döndüren Exception'a bir uzantı ekledim:

public static class Extensions
{
    public static string ExceptionInfo(this Exception exception)
    {

        StackFrame stackFrame = (new StackTrace(exception, true)).GetFrame(0);
        return string.Format("At line {0} column {1} in {2}: {3} {4}{3}{5}  ",
           stackFrame.GetFileLineNumber(), stackFrame.GetFileColumnNumber(),
           stackFrame.GetMethod(), Environment.NewLine, stackFrame.GetFileName(),
           exception.Message);

    }
}

-3

Global.resx dosyasında Application_Error adlı bir olay var

bir hata oluştuğunda patlar, hata hakkında kolayca bilgi alabilir ve hata izleme e-postasına gönderebilirsiniz.

Ayrıca tüm u yapmanız gereken global.resx derlemek ve bin klasörünüze dll's (2 dlls) eklemek olduğunu düşünüyorum ve işe yarayacak!

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.