例外をスローした行番号を取得するにはどうすればよいですか?


198

ではcatchブロック、どのように私は例外をスローした行番号を取得することができますか?


実行時にはソースコードはありません。この行は何のために使用されますか?デバッグ時に、IDEは例外をスローする行を明確に示します。
ankitjaininfo 2010



IDEがない場合、@ ankitjaininfo 役に立ちません
マイケル

これはあなたの質問に答えますか?例外処理の行番号を表示
リアム

回答:


280

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(ex、True))。GetFrame(0).GetFileLineNumber()で、イミディエイトウィンドウからのVB単一行。
ジョナサン

34
C#ワンライナー:int line = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
gunwin 2013

17
これは常に0を返します。これは、pdbファイルがないことが原因ですか?それとは何ですか?(私はASP.netを使用しています)
Brabbeldas 2013

17
なぜGetFrame(0)を使用しているのですか?GetFrame(FrameCount-1)を使用する必要があると思います。
Dewald Swanepoel、2015年

9
@DewaldSwanepoelを使用GetFrame(st.FrameCount-1)するという提案がはるかに信頼性が高いことがわかりました。
ブラッドマーティン

75

簡単な方法は、 Exception.ToString()関数を、例外の説明の後に行を返します。

アプリケーション全体に関するデバッグ情報/ログが含まれているため、プログラムデバッグデータベースを確認することもできます。


さて、MSDNは、「現在の例外の文字列表現を作成して返す」とは異なって考えています
。msdn.microsoft.com

あなたは次のように何かを得る: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 2016

3
この回答に賛成票がこれ以上ないのは異常です。これは単純で、確実に機能し、PDBの警告には付属していません。
Nick Painter 2017年

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
残念ながら、英語以外のOSでは動作しません(「行」の単語はロケールによって異なります)。
Ivan Kochurkin、2015

2
@KvanTTTあなたは使うことができRegex.Match:[^ ]+ (\d+)、同じ効果のために。
Dan Bechard 2017年

ex.StackTraceには:line ありませんし、PDBファイルもないので、この回答は機能しません。
好戦的なチンパンジー

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

私はソリューション@ Byvy-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

行、列、メソッド、ファイル名、メッセージを返す拡張機能をExceptionに追加しました。

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つのdll)をbinフォルダーに追加するだけで、うまくいくと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.