ฉันจะรับหมายเลขบรรทัดที่มีข้อยกเว้นได้อย่างไร


198

ในcatchบล็อกฉันจะรับหมายเลขบรรทัดที่แสดงข้อยกเว้นได้อย่างไร


ที่รันไทม์ไม่มีซอร์สโค้ด สิ่งที่บรรทัดนี้จะไม่ใช้สำหรับ? ณ เวลาดีบั๊ก IDE จะแสดงบรรทัดที่ส่งข้อยกเว้นอย่างชัดเจน
ankitjaininfo



@ankitjaininfo ไม่เป็นประโยชน์หากไม่มี IDE!
Michael

สิ่งนี้ตอบคำถามของคุณหรือไม่ แสดงหมายเลขบรรทัดในการจัดการข้อยกเว้น
Liam

คำตอบ:


281

หากคุณต้องการหมายเลขบรรทัดสำหรับมากกว่าแค่การติดตามรูปแบบสแต็กที่คุณได้รับจาก Exception.StackTrace คุณสามารถใช้คลาส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();
}

โปรดทราบว่าจะใช้งานได้เฉพาะในกรณีที่มีไฟล์ pdb สำหรับแอสเซมบลีเท่านั้น


2
(ใหม่ StackTrace (เช่น True)) GetFrame (0) .GetFileLineNumber () สำหรับ VB บรรทัดเดียวจากหน้าต่างทันที
Jonathan

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

17
นี่จะคืนค่า 0 สำหรับฉันเสมอ สิ่งนี้เกิดจากไม่มีไฟล์ pdb หรือไม่? มันคืออะไรและจะได้รับมันได้อย่างไร (ฉันใช้ ASP.net)
Brabbeldas

17
ทำไมคุณใช้ GetFrame (0) ฉันคิดว่าคุณควรใช้ GetFrame (FrameCount-1)
Dewald Swanepoel

9
ฉันได้พบ @DewaldSwanepoel คำแนะนำการใช้GetFrame(st.FrameCount-1)เพื่อให้มีความน่าเชื่อถือมากขึ้น
แบรดมาร์ติน

75

วิธีง่าย ๆ ใช้Exception.ToString()ฟังก์ชั่นมันจะกลับบรรทัดหลังจากคำอธิบายข้อยกเว้น

คุณยังสามารถตรวจสอบฐานข้อมูลการดีบักของโปรแกรมเนื่องจากมีข้อมูล / บันทึกการดีบักเกี่ยวกับแอปพลิเคชันทั้งหมด


MSDN คิดต่างกันว่ามัน "สร้างและคืนค่าการแสดงสตริงของข้อยกเว้นปัจจุบัน": 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
ศาสตราจารย์แห่งการเขียนโปรแกรม

3
นี่ควรเป็นคำตอบที่ยอมรับได้ ฉันมักจะไปหา ex.message และสงสัยว่าทำไม VB.net ที่โง่เง่าจึงไม่สามารถรับข้อมูลเช่นเดียวกับใน Java ได้
Matthis Kohli

3
มันเป็นบ้าว่าคำตอบนี้ไม่มี upvotes มากขึ้น นี่เป็นเรื่องง่ายทำงานได้อย่างน่าเชื่อถือและไม่ได้มาพร้อมกับคำเตือน PDB
Nick Painter

9
Exception.Messageฉันตายแล้ว ไม่มีอีกครั้ง.
Reinstate โมนิก้า Cellio

27

หากคุณไม่มี.PBOไฟล์:

ค#

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

หรือเป็นขอบเขตในคลาสข้อยกเว้น

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
น่าเสียดายที่ไม่สามารถใช้งานได้ในระบบปฏิบัติการที่ไม่ใช่ภาษาอังกฤษ (คำว่า "บรรทัด" ขึ้นอยู่กับสถานที่)
Ivan Kochurkin

2
@ KvanTTT คุณสามารถใช้Regex.Matchกับเอ:[^ ]+ (\d+)ฟเฟกต์เดียวกันได้
Dan Bechard

คำตอบนี้ไม่ได้ผลสำหรับฉันเนื่องจาก ex.StackTrace ไม่มี:line และฉันไม่มีไฟล์ PDB
Chimpanzee Warlike

18

คุณสามารถรวม.PDBไฟล์สัญลักษณ์ที่เกี่ยวข้องกับแอสเซมบลีซึ่งประกอบด้วยข้อมูลเมตาดาต้าและเมื่อมีการโยนข้อยกเว้นมันจะมีข้อมูลแบบเต็มในสแต็คสแต็คที่ซึ่งข้อยกเว้นนี้เกิดขึ้น มันจะมีหมายเลขบรรทัดของแต่ละวิธีในสแต็ก


เราจะรวม PDB ด้วยวิธีใด? มีวิธีการรวม PDB เข้ากับแอปพลิเคชัน / ลงทะเบียนกับ GAC หรือไม่?
Jacob Persi


6

ตรวจสอบอันนี้

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

อัปเดตเป็นคำตอบ

    // 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

ฉันลองใช้วิธีแก้ปัญหาโดย @ davy-c แต่มีข้อยกเว้น "System.FormatException: 'อินพุตสตริงไม่ได้อยู่ในรูปแบบที่ถูกต้อง'" นี่เป็นเพราะยังมีข้อความผ่านหมายเลขบรรทัดฉันแก้ไขรหัสที่เขา โพสต์และมาด้วย:

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

สิ่งนี้ใช้ได้กับฉันใน VS2017 C #


0

วิธีการขยาย

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

การใช้

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

ทำงานให้ฉัน:

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

ฉันเพิ่มส่วนขยายในข้อยกเว้นซึ่งส่งคืนบรรทัดคอลัมน์วิธีชื่อไฟล์และข้อความ:

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 มีเหตุการณ์ชื่อ Application_Error

มันจะยิงเมื่อมีข้อผิดพลาดเกิดขึ้นคุณสามารถรับข้อมูลเกี่ยวกับข้อผิดพลาดได้อย่างง่ายดายและส่งไปยังอีเมลติดตามข้อผิดพลาด

นอกจากนี้ฉันคิดว่าทุกสิ่งที่คุณต้องทำคือการรวบรวม global.resx และเพิ่ม dll ของมัน (2 ที่กำลัง) ไปยังโฟลเดอร์ถังขยะของคุณและมันจะทำงาน!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.