我想获取导致错误的代码行数。例如;
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,所以我必须得到这个数字。
由于
答案 0 :(得分:21)
尝试这个简单的黑客:
首先将此(扩展)类添加到命名空间(大多数是顶级类):
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();
}
答案 1 :(得分:9)
试试这个
要获取StackTrace中的行号,您需要在dll / exes旁边拥有正确的调试信息(PDB文件)。要生成调试信息,请在Project Properties -> Build -> Advanced -> Debug Info
中设置选项:
将其设置为full
就足够了(有关其他选项的作用,请参阅MSDN docs)。默认情况下会为Debug构建配置生成调试信息(即PDB文件),但也可以为Release构建配置生成调试信息(即PDB文件)。
为发布版本生成PDB使您可以在没有PDB的情况下发送代码,但是如果需要行号(甚至连接远程调试器),则将PDB放在dll旁边。需要注意的一点是,在发布版本中,由于编译器或JIT编译器的优化,行号可能不完全正确(如果行号显示为0,则尤其如此)。
答案 2 :(得分:7)
问题在于您正在尝试获取异常的第一帧的行号:
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()的调用发生的堆栈中。
我想知道,你需要什么样的唯一的亚麻布,为什么不只是记录/打印/无论完整的堆栈跟踪。至少出于诊断原因,无论如何都要有用。
答案 3 :(得分:5)
如果未初始化StackTrace以包含fileinfo,则结果可能为0。
试试这个
try
{
//code
}
catch (Exception e)
{
var lineNumber = new System.Diagnostics.StackTrace(e, true).GetFrame(0).GetFileLineNumber();
}
这对我有用。
答案 4 :(得分:4)
您可以使用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();
}
}
答案 5 :(得分:4)
这是从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}";
快乐调试!
答案 6 :(得分:1)
要获取行号,您需要应用程序处于调试模式或,在同一文件夹(.pdb文件)中包含调试符号,以显示行号。您发布的代码应该可以正常工作。
答案 7 :(得分:0)
以下代码异常日志处理程序方法正常工作:
抓住:中的
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日志文件如下所示:
<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>
答案 8 :(得分:0)
在.NET 4.5中,您可以使用ExceptionDispatchInfo重新抛出异常而不是经典// Check for login status when changing page URL
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
var currentRoute = toState.name;
$rootScope.authenticated = false;
if ($auth.isAuthenticated()) {
$rootScope.authenticated = true;
}
(确保PDB文件存在或不显示行号):
throw;
来源:blogpost。 Windows上的PDB文件don't decrease performance。
答案 9 :(得分:-1)
使用可以抛出的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
第一行显示异常的类型和消息。第二行显示抛出异常的文件,函数和行号