Как получить номер строки ошибки кода, используя try-catch - PullRequest
30 голосов
/ 01 декабря 2011

Я хочу получить номер строки кода, который вызывает ошибку. Например;

static void Main(string[] args)
{
    using (SqlConnection conn = new SqlConnection(bagcum))
    {
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = "DONTINSERT into GIVEMEERROR(CamNo,Statu) values (" + 23 + "," + 0 + ")";
        conn.Open();
        int n = cmd.ExecuteNonQuery();
    }
}

Так как мы знаем, что код не работает, он выдаст исключение Номер строки кода, который:

int n = cmd.ExecuteNonQuery();

Так как же получить номер этой строки, используя try-catch? Я попытался использовать класс StackTrace, но он дает номер строки как 0:

static void Main(string[] args)
{
    try
    {
        using (SqlConnection conn = new SqlConnection(bagcum))
        {
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = "DONTINSERT into GIVEMEERROR(CamNo,Statu) values (" + 23 + "," + 0 + ")";
            conn.Open();
            int n = cmd.ExecuteNonQuery();
        }        
    }
    catch (Exception ex)
    {
        System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);            
        Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
    }
}

ВЫВОД:

Line:0

Обновление:
Обычно строка ошибки кода 22, поэтому я должен получить это число.

Спасибо

Ответы [ 10 ]

21 голосов
/ 06 июля 2012

Вместо этого попробуйте этот простой взлом:

Сначала добавьте этот (дополнительный) класс в ваше пространство имен (в основном это класс верхнего уровня):

public static class ExceptionHelper
{
    public static int LineNumber(this Exception e)
    {

        int linenum = 0;
        try
        {
            //linenum = Convert.ToInt32(e.StackTrace.Substring(e.StackTrace.LastIndexOf(":line") + 5));

            //For Localized Visual Studio ... In other languages stack trace  doesn't end with ":Line 12"
            linenum = Convert.ToInt32(e.StackTrace.Substring(e.StackTrace.LastIndexOf(' ')));

        }


        catch
        {
            //Stack trace is not available!
        }
        return linenum;
    }
}

И все готово! Используйте метод LineNumber всякий раз, когданужно это:

try
{
//Do your code here
}
catch (Exception e)
{
int linenum = e.LineNumber();
}
9 голосов
/ 01 декабря 2011

попробуйте это

Чтобы получить номера строк в StackTrace, вам необходимо иметь правильную отладочную информацию (файлы PDB) вместе с вашими dll / exes.Чтобы сгенерировать отладочную информацию, установите параметр в Project Properties -> Build -> Advanced -> Debug Info:

alt text

Достаточно установить его на full (см. Документы MSDN длячто делают другие варианты).Информация об отладке (т. Е. Файлы PDB) создаются для конфигураций сборки Debug по умолчанию, но также могут создаваться для конфигураций сборки Release.

Создание PDB для сборок релизов позволяет вам отправлять код без PDB, но отбрасывать PDB рядом с dll, если вам нужны номера строк (или даже для подключения удаленного отладчика).Стоит отметить, что в сборке релиза номера строк могут быть не совсем корректными из-за оптимизаций, сделанных компилятором или JIT-компилятором (это особенно важно, если номера строк отображаются как 0).

7 голосов
/ 20 января 2012

Проблема в том, что вы пытаетесь получить номер строки первого кадра исключения:

System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());

Однако, исключение не происходит в строке, которую вынапишите ExecuteNonQuery, но где-нибудь внутри этой функции, возможно, несколько кадров стека (т.е. вызовы вложенных функций) глубже.Таким образом, первый кадр (который вы явно извлекаете с помощью GetFrame(0)) находится где-то внутри кода Microsoft (скорее всего, System.Data.dll), для которого у вас нет отладочных символов.

Запишите полную трассировку стека исключений вваша функция, чтобы понять, что я имею в виду:

try
{
   // your code ...
}
catch (Exception ex) 
{
   Console.WriteLine(ex);
}

Если не считать синтаксического анализа трассировки стека (например, ex.StackTrace), нет надежных причин, почему нужно получить номер белья вызова "ExecuteNonQuery ()".Я бы особенно не попытался подсчитать кадры стека вверх по стеку, где происходит ваш вызов ExecuteNonQuery ().

Однако мне интересно, для чего вам нужен единственный номер белья, почему бы просто не записать /Напечатайте / независимо от полной трассировки стека.По крайней мере, из-за диагностических причин, которые в любом случае гораздо полезнее.

5 голосов
/ 23 марта 2014

Вы можете получить 0 в результате, если вы не инициализируете StackTrace для включения fileinfo.

enter image description here

Попробуйте это

try
{
    //code
}
catch (Exception e)
{
    var lineNumber = new System.Diagnostics.StackTrace(e, true).GetFrame(0).GetFileLineNumber();
}

Это сработало для меня.

4 голосов
/ 15 ноября 2015

Вот довольно простой способ получить кучу информации из объекта Exception: просто добавьте такой код в любые потенциально вызывающие исключения методы:

catch (Exception ex)
{
    String exDetail = String.Format(ExceptionFormatString, ex.Message, Environment.NewLine, ex.Source, ex.StackTrace);
    MessageBox.Show(exDetail);
}

Информация, которую вы получаете, часто будет более конкретнойособенно в отношении номеров строк, в которых возникают проблемы, чем вы могли бы видеть в противном случае.

Возможно, вы заметили, что String.Format () использует константу, а именно «ExceptionFormatString».Это хорошая практика, так что если вы хотите изменить его, после добавления приведенного выше кода в 40-одиннадцать методов, вы можете просто изменить его в одном месте.В любом случае, вот оно:

public static readonly String ExceptionFormatString = "Exception message: {0}{1}Exception Source: {2}{1}Exception StackTrace: {3}{1}";

Счастливая отладка!

4 голосов
/ 20 января 2012

Вы можете использовать класс System.Diagnostics.StackTrace , как показано ниже:

public void MethodName()
{
    try
    {
        throw new Exception();
    }
    catch (Exception ex)
    {
        // Get stack trace for the exception with source file information
        var trace = new StackTrace(ex, true);

        // Get the top stack frame
        var frame = trace.GetFrame(0);

        // Get the line number from the stack frame
        var line = frame.GetFileLineNumber();
    }
}
1 голос
/ 01 декабря 2011

Чтобы получить номера строк, ваше приложение должно находиться в режиме отладки. или включают символы отладки в той же папке (файл .pdb), чтобы номера строк отображались. Код, который вы отправили, должен работать.

0 голосов
/ 16 декабря 2016

В .NET 4.5 вы можете использовать ExceptionDispatchInfo для переброса ваших исключений вместо классического throw; (убедитесь, что файлы PDB есть, или номера строк не будут отображаться):

    static void A()
    {
        try
        {
            throw new Exception("A");
        }
        catch (Exception e)
        {
            ExceptionDispatchInfo.Capture(e).Throw();
        }
    }

Источник: blogpost . Файлы PDB не снижают производительность в Windows.

0 голосов
/ 15 марта 2015

следующий метод обработчика журнала исключений кода работает нормально:

in catch :

 catch (Exception ex)
            {
                CommonTools.vAddToLog(ex, EmpID, ErrorCodes.UnDefined);
                Response.Redirect("~/ErrorPage.aspx");
            }

in AddToLog метод:

 string _exMsgErr = string.Empty;
                var frame = oStackTrace.FrameCount > 1 ? oStackTrace.GetFrame(1) : oStackTrace.GetFrame(0);
                if (oException.GetType() == typeof(JOVALException))
                {
                    JOVALException _JOVALEx = (JOVALException)oException;
                    _exMsgErr = _JOVALEx.Message;
                }
                else
                {
                    _exMsgErr = oException.Message;
                }
                ErrorLog oError = new ErrorLog(frame.GetMethod().Name, (string)frame.GetFileName(), (int)frame.GetFileLineNumber(), sCustomErrorMessage == string.Empty ? _exMsgErr : sCustomErrorMessage, sUserID, oErrCode);
                //Cont. your code of log file

Наконец, XML-файл журнала выглядит следующим образом:

<ErrorLog>
<MethodName>FillRolesDDLs</MethodName>
<FileName>
F:\Projects\ERP\ERP\Pages\SystemSettings\Roles.aspx.cs
</FileName>
<LineNumber>61</LineNumber>
<ErrorMesssage>
The given DataRow is not in the current DataRowCollection.
</ErrorMesssage>
<UserID>1</UserID>
<ErrCode>UnDefined</ErrCode>
<Time>15/03/2015 16:23:21.976</Time>
</ErrorLog>
0 голосов
/ 01 декабря 2011

Скопируйте всю трассировку стека в строку или построитель строк с помощью try / catch, который может выдать, см. Пример ниже

try
{
    //Do some programming
}
catch(Exception ex)
{

   //Catch the exception and assign the stack trace
   StackTrace = ex;
}

Вывод будет

System.IndexOutOfRangeException: Index was outside the bounds of the array.   
at Program.Run() in C:\Console Application1\Program.cs:line 37    
at Program.Main(String[] args) in C:\Console Application1\Program.cs:line 45 
* 1006Первая строка показывает тип исключения и сообщение.Вторая строка показывает файл, функцию и номер строки, в которую было сгенерировано исключение
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...