Làm thế nào tôi có thể có được số dòng đã ném ngoại lệ?


198

Trong một catchkhối, làm cách nào tôi có thể nhận được số dòng đã ném ngoại lệ?


tại thời gian chạy không có mã nguồn. dòng này sẽ không được sử dụng để làm gì? tại thời điểm gỡ lỗi, IDE hiển thị rõ ràng dòng ném ngoại lệ.
ankitjaininfo



@ankitjaininfo không hữu ích nếu không có IDE!
Michael

Điều này có trả lời câu hỏi của bạn không? Hiển thị số dòng trong xử lý ngoại lệ
Liam

Câu trả lời:


280

Nếu bạn cần số dòng không chỉ là dấu vết ngăn xếp được định dạng mà bạn nhận được từ Exception.StackTrace, bạn có thể sử dụng lớp 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();
}

Lưu ý rằng điều này sẽ chỉ hoạt động nếu có tệp pdb có sẵn để lắp ráp.


2
? (StackTrace mới (ví dụ: True)). GetFrame (0) .GetFileLineNumber () cho dòng đơn VB từ cửa sổ ngay lập tức.
Jonathan

34
Lớp lót C #:int line = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
gunwin

17
Điều này luôn trả về 0 cho tôi. Điều này có phải do không có tệp pdb không? Nó là gì và làm thế nào để có được nó? (Tôi đang sử dụng ASP.net)
Brabbeldas

17
Tại sao bạn sử dụng GetFrame (0)? Tôi nghĩ rằng bạn nên sử dụng GetFrame (FrameCount-1).
Dewald Swanepoel

9
Tôi đã tìm thấy gợi ý sử dụng @DewaldSwanepoel GetFrame(st.FrameCount-1)đáng tin cậy hơn nhiều.
Brad Martin

75

Cách đơn giản, sử dụng Exception.ToString()hàm, nó sẽ trả về dòng sau mô tả ngoại lệ.

Bạn cũng có thể kiểm tra cơ sở dữ liệu gỡ lỗi chương trình vì nó chứa thông tin / nhật ký gỡ lỗi về toàn bộ ứng dụng.


Vâng MSDN nghĩ khác, rằng nó "Tạo và trả về một chuỗi đại diện của ngoại lệ hiện tại": msdn.microsoft.com/en-us/l
Library / trộm

Bạn nhận được một cái gì đó tương tự như:System.Exception: Test at Tests.Controllers.HomeController.About() in c:\Users\MatthewB\Documents\Visual Studio 2013\Projects\Tests\Tests\Controllers\HomeController.cs:line 22
Giáo sư lập trình

3
Đây phải là câu trả lời được chấp nhận. Tôi luôn đi ex.message và tự hỏi tại sao VB.net ngu ngốc không thể có được thông tin giống như trong Java.
Matthis Kohli

3
Thật điên rồ khi câu trả lời này không có nhiều sự ủng hộ hơn. Điều này là đơn giản, hoạt động đáng tin cậy và không đi kèm với các cảnh báo PDB.
Nick Họa sĩ

9
Exception.Messagelà chết với tôi Không bao giờ lặp lại.
Phục hồi Monica Cellio

27

Nếu bạn không có .PBOtập tin:

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

Hoặc như một mức độ trên lớp Ngoại lệ

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
Thật không may sẽ không hoạt động trong hệ điều hành không phải tiếng Anh (từ "dòng" phụ thuộc vào ngôn ngữ).
Ivan Kochurkin

2
@KvanTTT Bạn có thể sử dụng Regex.Matchvới :[^ ]+ (\d+)cho tác dụng tương tự.
Dan Bechard

Câu trả lời này không phù hợp với tôi, vì ex.StackTrace không có :line và tôi không có tệp PDB.
Tinh tinh hiếu chiến

18

Bạn có thể bao gồm .PDBcác tệp biểu tượng được liên kết với tập hợp có chứa thông tin siêu dữ liệu và khi ném ngoại lệ, nó sẽ chứa thông tin đầy đủ trong ngăn xếp nơi bắt nguồn của ngoại lệ này. Nó sẽ chứa số dòng của mỗi phương thức trong ngăn xếp.


Làm thế nào một người sẽ đi về bao gồm một PDB? Có cách nào để đóng gói PDB vào ứng dụng / đăng ký nó với GAC không?
Jacob Persi


6

Kiểm tra cái này

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

Cập nhật câu trả lời

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

Tôi đã thử sử dụng giải pháp By @ deef-c nhưng có Ngoại lệ "System.FormatException: 'Chuỗi đầu vào không đúng định dạng.'", Điều này là do vẫn còn văn bản qua số dòng, tôi đã sửa đổi mã anh ấy đăng và đưa ra:

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

Điều này làm việc cho tôi trong VS2017 C #.


0

Phương pháp mở rộng

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

Sử dụng

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

Làm việc cho tôi:

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

Tôi đã thêm một phần mở rộng vào Exception để trả về dòng, cột, phương thức, tên tệp và thông báo:

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

Trong tệp Global.resx có một sự kiện gọi là Application_Error

nó kích hoạt bất cứ khi nào xảy ra lỗi ,, bạn có thể dễ dàng nhận được bất kỳ thông tin nào về lỗi đó và gửi nó đến một email theo dõi lỗi.

Ngoài ra tôi nghĩ rằng tất cả những gì bạn cần làm là biên dịch global.resx và thêm dll's (2 dlls) vào thư mục bin của bạn và nó sẽ hoạt động!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.