故事: 我有来自3个不同班级的3个功能。调用命令的函数是:
Form1_Load(...)
- > Student.GetAllStudents(...)
- > StudentDAL.GetStudentInformation(...)
- > {{ 1}}
我想要做的是在 Form1中的ConnectionManager.GetConnection(...)
中显示 最内部函数的StackTrace,即ConnectionManager.GetConnection()
类的。换句话说,我不想在任何内部类中使用MessageBox
,而只在 Form1类的外部类中使用。
问题: 要获取内部异常,我们可以使用MessageBox
或InnerException
等,但当我尝试获取内部异常时,它会抛出异常“对象引用未设置为实例”,表示没有内部异常,当我检查时,该值也是GetBaseException()
。我想知道为什么它是null
?它不应该持有对内部异常的引用吗?如果我错了,请纠正我。
功能代码:
null
Form1_Load(...)
private void Form1_Load(object sender, EventArgs e)
{
try
{
DataTable dt = new DataTable();
dt.Load((**new Student().GetAllStudents()**));
if (dt.Rows.Count <= 0)
{
MessageBox.Show("Student table empty.");
}
else
{
this.dataGridView1.DataSource = dt;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message+Environment.NewLine+"Source(s) : "+ex.StackTrace.Substring(0, ex.StackTrace.LastIndexOf("at")));
}
GetAllStudents(...)
public SqlDataReader GetAllStudents()
{
try
{
return StudentInformationDataAccessLayer.GetStudentInformation();
}
catch (Exception ex)
{
throw ex;
}
}
GetStudentInformation(...)
public static SqlDataReader GetStudentInformation()
{
try
{
SqlConnection sqlCon = null;
sqlCon = ConnectionManager.GetConnection();
if (sqlCon == null)
{
return null;
}
String Query = null;
Query = "SELECT * FROM [dbo].[Student]";
SqlCommand cmd = new SqlCommand(Query, sqlCon);
SqlDataReader dr = null;
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return dr;
}
catch (Exception ex)
{
throw ex;
}
}
GetConnection(...)
答案 0 :(得分:2)
如果要保留堆栈跟踪和异常信息,则应更改重新引发捕获的异常的代码,如下所示:
}
catch(Exception ex)
{
// do what you need to do with ex
// ..
// rethrow..
throw; // notice this is not "throw ex";
}
仅使用throw;
重新抛出异常会保留原始堆栈跟踪。不一定是内在的例外,但这不是你应该关心的。您需要知道的是发生异常的堆栈跟踪。
答案 1 :(得分:1)
如果您想使用内部异常集重新抛出,请使用下面的代码,但请记住,将丢失堆栈跟踪:
try
{
...
}
catch (Exception ex)
{
throw new Exception("message", ex);
}
要重新抛出异常并保留堆栈跟踪,请使用:
try
{
...
}
catch (Exception ex)
{
throw;
}
答案 2 :(得分:1)
并非每个异常都确实存在内部异常。首先检查内部ex是null
,如果不是,则处理它。
说完这句话之后,你当然可以重新抛出你的异常,如下所示:
catch(Exception ex)
{
// so smth
// ..
// rethrow..
throw;
}
但请记住两件事:
请勿键入throw ex
,只需throw
。
只有在重新抛出之前确实想要对此异常执行某些操作时才执行此操作。如果你没有这样的计划,就不要在这个级别上抓住它。
答案 3 :(得分:0)
我会做类似的事情:
try
{
...
}
catch (Exception ex)
{
if (ex.InnerException == null)
throw ex;
else
throw ex.InnerException;
}
然后在你想要进行堆栈跟踪的某个时刻,按照以下方式做一些事情:
StackTrace trace = new StackTrace(System.Threading.Thread.CurrentThread, true);
StackFrame[] frames = trace.GetFrames();
string result = string.Empty;
foreach (StackFrame sf in frames)
{
string += sf.GetMethod().Name;
}
MessageBox(result);