catch
Wie kann ich in einem Block die Zeilennummer ermitteln, die eine Ausnahme ausgelöst hat?
catch
Wie kann ich in einem Block die Zeilennummer ermitteln, die eine Ausnahme ausgelöst hat?
Antworten:
Wenn Sie die Zeilennummer nicht nur für den formatierten Stack-Trace benötigen, den Sie von Exception.StackTrace erhalten, können Sie die StackTrace- Klasse verwenden:
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();
}
Beachten Sie, dass dies nur funktioniert, wenn für die Assembly eine PDF-Datei verfügbar ist.
int line = (new StackTrace(ex, true)).GetFrame(0).GetFileLineNumber();
GetFrame(st.FrameCount-1)
, weitaus zuverlässiger zu sein.
Verwenden Sie auf einfache Weise die Exception.ToString()
Funktion, um die Zeile nach der Ausnahmebeschreibung zurückzugeben.
Sie können auch die Programm-Debug-Datenbank überprüfen, da sie Debug-Informationen / Protokolle über die gesamte Anwendung enthält.
System.Exception: Test at Tests.Controllers.HomeController.About() in c:\Users\MatthewB\Documents\Visual Studio 2013\Projects\Tests\Tests\Controllers\HomeController.cs:line 22
Exception.Message
ist tot für mich. Nie wieder.
Wenn Sie die .PBO
Datei nicht haben :
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
Oder als Erweiterung der Exception-Klasse
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;
}
}
Regex.Match
mit :[^ ]+ (\d+)
für den gleichen Effekt verwenden.
:line
und ich die PDB-Datei nicht habe.
Sie können .PDB
der Assembly zugeordnete Symboldateien einschließen , die Metadateninformationen enthalten. Wenn eine Ausnahme ausgelöst wird, enthält sie vollständige Informationen in der Stapelverfolgung, aus der diese Ausnahme stammt. Es enthält die Zeilennummern jeder Methode im Stapel.
Es klappt:
var LineNumber = new StackTrace(ex, True).GetFrame(0).GetFileLineNumber();
UnhandledExceptionEventArgs
Objekt
Überprüfen Sie dieses
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();
Update auf die Antwort
// 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();
Ich habe versucht, die Lösung By @ davy-c zu verwenden, hatte aber die Ausnahme "System.FormatException: 'Eingabezeichenfolge hatte nicht das richtige Format.'". Dies lag daran, dass nach der Zeilennummer immer noch Text vorhanden war. Ich habe den Code geändert gepostet und kam mit:
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 ", ""));
Dies funktioniert bei mir in VS2017 C #.
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);
}
Arbeiten für mich:
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();
Ich habe der Ausnahme eine Erweiterung hinzugefügt, die die Zeile, Spalte, Methode, den Dateinamen und die Nachricht zurückgibt:
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);
}
}
In der Datei Global.resx gibt es ein Ereignis namens Application_Error
Es wird ausgelöst, wenn ein Fehler auftritt. Sie können problemlos Informationen zu dem Fehler abrufen und diese an eine E-Mail zur Fehlerverfolgung senden.
Ich denke auch, alles was Sie tun müssen, ist die Datei global.resx zu kompilieren und ihre DLLs (2 DLLs) zu Ihrem Bin-Ordner hinzuzufügen, und es wird funktionieren!