Vb.net ASP.NET中显示异常消息的递归方法
我已经开始大量使用异常,我相信我会从中成长出来,以一种艰难的方式学习优缺点,但在我成为异常大师之前,我想知道这种技术是否可以接受 我打算将数据库异常包装在我自己的“SorryFailedToSaveYourData”异常中,然后在异常中递归移动,显示消息,有点像这样:Vb.net ASP.NET中显示异常消息的递归方法,vb.net,exception,recursion,messages,Vb.net,Exception,Recursion,Messages,我已经开始大量使用异常,我相信我会从中成长出来,以一种艰难的方式学习优缺点,但在我成为异常大师之前,我想知道这种技术是否可以接受 我打算将数据库异常包装在我自己的“SorryFailedToSaveYourData”异常中,然后在异常中递归移动,显示消息,有点像这样: Try DoSomeWork Catch BuildErrorMessage(lblError,ex) End Try Public Sub BuildErrorMessage(ByVal lbl As Labe
Try
DoSomeWork
Catch
BuildErrorMessage(lblError,ex)
End Try
Public Sub BuildErrorMessage(ByVal lbl As Label, ByVal ex As Exception)
lbl.Text += "<br />" & ex.Message
While Not ex.InnerException Is Nothing
BuildErrorMessage(lbl, ex.InnerException)
End While
End Sub
试试看
DoSomeWork
抓住
BuildErrorMessage(lblError,ex)
结束尝试
公共子构建错误消息(ByVal lbl作为标签,ByVal ex作为例外)
lbl.Text+=“
”和ex.消息
而不是ex.InnerException什么都不是
BuildErrorMessage(lbl,例如InnerException)
结束时
端接头
这种做法有用吗?或者说,在处理异常时,我完全错过了机会?我知道您可以创建自己的异常,但对于我们正在进行的项目的规模来说,这似乎有些过头了
感谢您在异常内部构建了一个标签,可能是因为您想向用户显示消息。如果您的异常跨越应用程序的多个层(您提到了包装您自己的数据异常),那么这是一个糟糕的想法,因为它将违反封装并强制您的异常处理使用UI元素。
不过,通常情况下,您不希望向用户显示错误消息。用户关心堆栈溢出发生了什么?他只关心应用程序是否损坏,以及是否记录了错误报告并将其发送给相应的团队。
通常,当且仅当应用程序处于无法再运行的状态时,才希望出现异常。如果它只是有条件地发生,您将希望显式地使用条件来处理它,以检查它,而不是使用异常机制
例如,如果您知道用户将从家中连接,但无法保证会有Internet连接,则检查Internet连接并显示一条消息,说明用户需要连接,而不仅仅是尝试使用Internet连接并在不存在异常时创建异常。您正在异常内部构建一个标签,可能是因为您想向用户显示消息。如果您的异常跨越应用程序的多个层(您提到了包装您自己的数据异常),那么这是一个糟糕的想法,因为它将违反封装并强制您的异常处理使用UI元素。
不过,通常情况下,您不希望向用户显示错误消息。用户关心堆栈溢出发生了什么?他只关心应用程序是否损坏,以及是否记录了错误报告并将其发送给相应的团队。
通常,当且仅当应用程序处于无法再运行的状态时,才希望出现异常。如果它只是有条件地发生,您将希望显式地使用条件来处理它,以检查它,而不是使用异常机制
例如,如果您知道用户将从家中连接,但无法保证会有Internet连接,则可以检查Internet连接并显示一条消息,说明用户需要连接,而不是仅尝试使用Internet连接,如果不存在,则创建异常。编辑 我一开始误解了你的问题,如果你向最终用户显示信息,你可能不想这样做。如果您要记录异常以便对后者进行故障排除,您将希望执行我建议的操作 ==== 这是标准的,尽管我也会捕获堆栈跟踪和数据属性中的任何项(尽管我没有看到任何框架代码使用这一点,您永远不会知道,如果您要抛出自己的异常或重新抛出异常,它会很有用) 尽管您的实际代码中有一个错误,但您很可能会在无限循环中结束,因为您的外部异常将始终有一个内部异常
Public Sub BuildErrorMessage(ByVal lbl As Label, ByVal ex As Exception)
lbl.Text += "<br />" & ex.Message
If Not ex.InnerException Is Nothing Then
BuildErrorMessage(lbl, ex.InnerException)
End If
End Sub
公共子构建错误消息(ByVal lbl作为标签,ByVal ex作为例外)
lbl.Text+=“
”和ex.消息
如果不是ex.InnerException,则什么都不是
BuildErrorMessage(lbl,例如InnerException)
如果结束
端接头
编辑
我一开始误解了您的问题,如果您向最终用户显示信息,您可能不想这样做。如果您要记录异常以便对后者进行故障排除,您将希望执行我的建议
====
这是标准的,尽管我也会捕获堆栈跟踪和数据属性中的任何项(尽管我没有看到任何框架代码使用这一点,您永远不会知道,如果您要抛出自己的异常或重新抛出异常,它会很有用)
尽管您的实际代码中有一个错误,但您很可能会在无限循环中结束,因为您的外部异常将始终有一个内部异常
Public Sub BuildErrorMessage(ByVal lbl As Label, ByVal ex As Exception)
lbl.Text += "<br />" & ex.Message
If Not ex.InnerException Is Nothing Then
BuildErrorMessage(lbl, ex.InnerException)
End If
End Sub
公共子构建错误消息(ByVal lbl作为标签,ByVal ex作为例外)
lbl.Text+=“
”和ex.消息
如果不是ex.InnerException,则什么都不是
BuildErrorMessage(lbl,例如InnerException)
如果结束
端接头
ex.ToString()将生成格式化的异常文本,您应该使用该文本而不是.Message,因为它可能不会提供调试所需的全部信息
我还建议在递归中传递stringbuilder,而不是使用AppendLine()传递标签,这样您还可以使用该文本发送电子邮件通知、编写事件查看器以及日志文件。要在UI中显示(看起来您需要html),只需将标签文本值设置为
StringBuilder.ToString().Replace(Environment.NewLine, "<br />")
StringBuilder.ToString().Replace(Environment.NewLine,
)
ex.ToString()将生成格式化的异常文本,您应该使用该文本而不是.Message,因为它可能不会提供调试所需的全部信息