Bagaimana saya bisa mendapatkan nomor baris yang melempar pengecualian?

198

Dalam sebuah catchblok, bagaimana saya bisa mendapatkan nomor baris yang melempar pengecualian?

MBZ
sumber
saat runtime tidak ada kode sumber. untuk apa baris ini tidak akan digunakan? pada waktu debug, IDE dengan jelas menunjukkan baris yang melempar pengecualian.
ankitjaininfo
1
kemungkinan duplikat nomor baris Perlihatkan dalam penanganan pengecualian
Thom Smith
@ankitjaininfo tidak membantu jika tidak ada IDE!
Michael
Apakah ini menjawab pertanyaan Anda? Tampilkan nomor baris dalam penanganan pengecualian
Liam

Jawaban:

280

Jika Anda membutuhkan nomor baris untuk lebih dari sekadar jejak tumpukan yang diformat yang Anda dapatkan dari Exception.StackTrace, Anda bisa menggunakan kelas StackTrace :

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

Perhatikan bahwa ini hanya akan berfungsi jika ada file pdb tersedia untuk majelis.

Quartermeister
sumber
2
? (New StackTrace (ex, True)). GetFrame (0) .GetFileLineNumber () untuk baris tunggal VB dari jendela langsung.
Jonathan
34
C # one liner:int line = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
gunwin
17
Ini selalu mengembalikan 0 untuk saya. Apakah ini disebabkan oleh tidak memiliki file pdb? Apa itu dan bagaimana cara mendapatkannya? (Saya menggunakan ASP.net)
Brabbeldas
17
Mengapa Anda menggunakan GetFrame (0)? Saya akan berpikir bahwa Anda harus menggunakan GetFrame (FrameCount-1).
Dewald Swanepoel
9
Saya telah menemukan saran @DewaldSwanepoel untuk menggunakan GetFrame(st.FrameCount-1)agar jauh lebih andal.
Brad Martin
75

Cara sederhana, gunakan Exception.ToString()fungsi, itu akan mengembalikan garis setelah deskripsi pengecualian.

Anda juga dapat memeriksa database debug program karena berisi info debug / log tentang seluruh aplikasi.

SimpleButPerfect
sumber
Yah MSDN berpikir berbeda, bahwa itu "Membuat dan mengembalikan representasi string dari pengecualian saat ini": msdn.microsoft.com/en-us/library/…
Prokurors
Anda mendapatkan sesuatu yang mirip dengan:System.Exception: Test at Tests.Controllers.HomeController.About() in c:\Users\MatthewB\Documents\Visual Studio 2013\Projects\Tests\Tests\Controllers\HomeController.cs:line 22
Profesor pemrograman
3
Ini harus menjadi jawaban yang diterima. Saya selalu pergi untuk ex.message dan bertanya-tanya mengapa VB.net bodoh tidak bisa mendapatkan informasi yang sama seperti di Jawa.
Matthis Kohli
3
Gila bahwa jawaban ini tidak memiliki lebih banyak suara positif. Ini sederhana, dapat diandalkan, dan tidak disertai dengan peringatan PDB.
Nick Painter
9
Exception.Messagesudah mati bagiku. Tidak akan lagi.
Pasang kembali Monica Cellio
27

Jika Anda tidak memiliki .PBOfile:

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

Atau sebagai perluasan pada kelas Exception

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;
    }
}   
radbyx
sumber
8
Sayangnya tidak akan berfungsi dalam OS bukan bahasa Inggris (kata "line" tergantung pada lokal).
Ivan Kochurkin
2
@KvanTTT Anda dapat menggunakan Regex.Matchdengan :[^ ]+ (\d+)untuk efek yang sama.
Dan Bechard
Jawaban ini tidak berfungsi untuk saya, karena ex.StackTrace tidak memiliki :line dan saya tidak memiliki file PDB.
Simpanse suka berperang
18

Anda bisa menyertakan .PDBfile simbol yang terkait dengan majelis yang berisi informasi metadata dan ketika pengecualian dilemparkan itu akan berisi informasi lengkap di stacktrace dari mana pengecualian ini berasal. Ini akan berisi nomor baris setiap metode dalam tumpukan.

Darin Dimitrov
sumber
Bagaimana cara memasukkan PDB? Apakah ada cara untuk menggabungkan PDB ke dalam aplikasi / mendaftarkannya ke GAC?
Jacob Persi
7

Berhasil:

var LineNumber = new StackTrace(ex, True).GetFrame(0).GetFileLineNumber();
Thirisangu Ramanathan
sumber
Bagaimana dengan pengecualian yang tidak ditangani? seperti UnhandledExceptionEventArgsobjek
Yousha Aleayoub
6

Periksa ini

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();
Ram Maurya
sumber
1

Perbarui ke jawabannya

    // 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();
Sean Fleming
sumber
1

Saya mencoba menggunakan solusi By @ davy-c tetapi memiliki Pengecualian "System.FormatException: 'String input tidak dalam format yang benar.'", Ini karena masih ada teks yang melewati nomor baris, saya memodifikasi kode diposting dan muncul dengan:

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 ", ""));

Ini bekerja untuk saya di VS2017 C #.

Joseph Michael
sumber
0

Metode Perpanjangan

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

Pemakaian

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);
}
Arvo Bowen
sumber
0

Bekerja untuk saya:

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();
Shivendra Singh
sumber
0

Saya menambahkan ekstensi ke Pengecualian yang mengembalikan baris, kolom, metode, nama file, dan pesan:

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

    }
}
vyengr
sumber
-3

Dalam file Global.resx ada acara yang disebut Application_Error

itu menyala setiap kali terjadi kesalahan, Anda dapat dengan mudah mendapatkan informasi tentang kesalahan, dan mengirimkannya ke email pelacakan bug.

Juga saya pikir semua yang perlu Anda lakukan adalah mengkompilasi global.resx dan menambahkan dll (2 dll) ke folder bin Anda dan itu akan bekerja!

Khaled
sumber