如何使用try-catch获取代码的错误行数

我想得到导致错误的代码行数。 例如;

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

所以我们知道代码不起作用,它会抛出exception行代码,它是:

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

OUTPUT:

 Line:0 

更新:
通常错误的代码行是22,所以我必须得到这个数字。

谢谢

试试这个简单的黑客:

首先将此(扩展)类添加到您的命名空间(大多数是顶级类):

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

试试这个

要获取StackTrace中的行号,您需要在dll / exes旁边拥有正确的调试信息(PDB文件)。 要生成调试信息,请在Project Properties -> Build -> Advanced -> Debug Info设置选项:

替代文字

将其设置为full应该足够(请参阅MSDN文档了解其他选项的用途)。 默认情况下会为Debug构建配置生成调试信息(即PDB文件),但也可以为Release构建配置生成调试信息(即PDB文件)。

为发布版本生成PDB使您可以在没有PDB的情况下发送代码,但是如果需要行号(甚至连接远程调试器),则将PDB放在dll旁边。 需要注意的一点是,在发布版本中,由于编译器或JIT编译器的优化,行号可能不完全正确(如果行号显示为0,则尤其如此)。

问题是你正在尝试获取exception的第一帧的行号:

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

但是,exception不是源于您编写ExecuteNonQuery的行,而是源于该函数中的某个位置,可能是多个堆栈帧(即嵌套函数调用)更深层次。 所以第一帧(你使用GetFrame(0)显式检索)是微软代码中的某个地方(很可能是System.Data.dll ),你没有任何调试符号。

在函数中写出完整的exception堆栈跟踪,看看我的意思:

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

如果没有解析堆栈跟踪(即ex.StackTrace),就没有可靠的原因来获取“ExecuteNonQuery()”调用的整数。 我特别不会尝试将堆栈帧计数到您调用ExecuteNonQuery()的堆栈中。

不过我想知道,你需要什么样的唯一的亚麻布,为什么不只是记录/打印/无论完整的堆栈跟踪。 至少出于诊断原因,无论如何都更有用。

您可以使用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(); } } 

如果不初始化StackTrace以包含fileinfo,则结果可能为0。

在此处输入图像描述

试试这个

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

这对我有用。

这是从Exception对象获取大量信息的一种相当简单的方法:只需将这样的代码添加到任何可能抛出exception的方法中:

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

您获得的信息通常会更具体,特别是关于出现问题的行号,而不是您可能看到的。

您可能已经注意到String.Format()使用常量,即“ExceptionFormatString”。 这是一个很好的做法,所以如果你想改变它,在将上面的代码添加到40-11方法之后,你可以把它改成一个地方。 无论如何,这里是:

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

快乐调试!

要获取行号,您需要应用程序处于调试模式将调试符号包含在同一文件夹(.pdb文件)中以显示行号。 您发布的代码应该可以正常工作。

以下代码exception日志处理程序方法工作正常:

捕获

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

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日志文件如下所示:

  FillRolesDDLs  F:\Projects\ERP\ERP\Pages\SystemSettings\Roles.aspx.cs  61  The given DataRow is not in the current DataRowCollection.  1 UnDefined   

在.NET 4.5中,您可以使用ExceptionDispatchInfo来重新抛出exception而不是经典throw; (确保PDB文件存在或不显示行号):

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

资料来源: blogpost 。 PDB文件不会降低 Windows上的性能 。

使用可以抛出的try / catch将整个堆栈跟踪复制到字符串或stringbuilder中,请参阅下面的示例

 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 

第一行显示exception的类型和消息。 第二行显示抛出exception的文件,函数和行号