Як я можу отримати номер рядка, який кинув виняток?


198

Як в catchблоці я можу отримати номер рядка, який викинув виняток?


під час виконання немає вихідного коду. для чого цей рядок не буде використовуватися? під час налагодження IDE чітко показує рядок, який видає виняток.
— ankitjaininfo



@ankitjaininfo не корисний, якщо немає IDE!
— Майкл

Чи відповідає це на ваше запитання? Показати номер рядка за винятком обробки
— Ліам

Відповіді:


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 (колишня, правда)). GetFrame (0) .GetFileLineNumber () для одного рядка VB з прямого вікна.
— Джонатан

34
C # one лайнер:int line = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
— gunwin

17
Це завжди повертає 0 для мене. Це викликано відсутністю файлу pdb? Що це таке і як його отримати? (Я використовую ASP.net)
— Brabbeldas

17
Чому ви використовуєте GetFrame (0)? Я думаю, що ви повинні використовувати GetFrame (FrameCount-1).
— Дьюальд Свенпоель

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.
— Маттіс Колі

3
Несумлінно, що ця відповідь не має більшої оцінки. Це просто, працює надійно і не поставляється із застереженнями PDB.
— Нік Пентер

9
Exception.Messageдля мене мертвий. Ніколи знову.
— Відновіть Моніку Селліо

27

Якщо у вас немає .PBOфайлу:

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

Або як розширення класу Виняток

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
На жаль, не буде працювати в не англійській ОС (слово "рядок" залежить від мови).
— Іван Кочуркін

2
@KvanTTT Ви можете використовувати Regex.Matchз :[^ ]+ (\d+)тим же ефектом.
— Ден Бешард

Ця відповідь не працює для мене, оскільки у ex.StackTrace немає, :line і у мене немає файлу PDB.
— Войовничий шимпанзе

18

Ви можете включити .PDBфайли символів, пов’язані з збіркою, які містять інформацію метаданих, і коли буде викинуто виняток, вона буде містити повну інформацію в стеці сліду, де цей виняток виник. Він буде містити номери рядків кожного методу в стеку.


Як можна було б включити ПТБ? Чи є спосіб поєднати ПТБ у додаток / зареєструвати його в GAC?
— Яків Персі


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

Я спробував використовувати рішення by @ 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 dlls) у вашу папку bin, і це буде працювати!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.