我已经开始使用try catch块了(有点晚了,我知道!),但现在我不知道一旦我抓住它就该如何处理异常。我该怎么办?
Try
connection.Open()
Dim sqlCmd As New SqlCommand("do some SQL", connection)
Dim sqlDa As New SqlDataAdapter(sqlCmd)
sqlDa.Fill(dt)
Catch ex As SQLException
' Ahhhh, what to do now!!!?
Finally
connection.Close()
End Try
答案 0 :(得分:64)
异常处理的经验法则 - 如果您不知道如何处理它,请不要抓住它。
对异常处理的经验法则进行计算 - 在最后一个负责任的时刻处理异常。如果你不知道这是否是最后一个负责任的时刻,那就不是。
答案 1 :(得分:23)
你想要它做什么?这完全取决于您的申请。
你可以让它重试,你可以在屏幕上显示一个消息框,写入日志,可能性是无穷无尽的。
作为开发人员,您无法预测每个可能的错误。即使您不知道如何修复错误,也可以使用通用捕获代码。您可能正在保存到数据库,并且可能会发生50个数据库错误之一,并且您将无法编写代码来处理每个错误。
你应该放入一个通用的catch来确保你的程序不只是崩溃,并且在某些情况下只是显示错误并让他们再次进行就足够了。想象一下,如果原因是“磁盘已满”。您只能打印出异常,让用户再试一次 - 他们知道该怎么做,并自己解决问题。
这就是为什么我不同意如果你不知道该怎么做就不处理它的评论。您应该始终处理它,即使它只是显示一个消息框说“错误”,因为它比“该程序执行了非法操作并将被关闭”无限好。
答案 2 :(得分:20)
这取决于您的业务逻辑,但您可能希望执行以下一项或多项操作。
您可能还希望检查异常是否属于上述类型之前可以处理的类型。
一篇关于VB.NET异常处理的好文章是Rajesh VS的 Exception Handling in VB.NET 。
答案 3 :(得分:14)
如果您不知道该怎么做,我会看到很多建议不要抓住它。这只是那种的权利。您应该捕获异常,但可能不在此级别。使用您的代码作为示例,我将更像这样写:
Using connection As New SqlConnection("connection string here"), _
sqlCmd As New SqlCommand("do some SQL", connection), _
sqlDa As New SqlDataAdapter(sqlCmd)
sqlDa.Fill(dt)
End Using
不仅没有Try / Catch /最后,没有开放或关闭。 .Fill()函数被记录为在需要时打开连接,并且Using块将确保它正确关闭,即使抛出异常。
这使您可以自由地捕获更高级别的异常 - 在UI或业务代码中调用运行查询的函数,而不是在查询本身。这个更高级别的代码可以更好地决定如何继续,需要发生什么日志记录,或向用户显示更好的错误消息。
事实上,正是这种异常的能力在你的代码中“冒泡”,使它们如此有价值。如果你总是在那里抛出一个异常,那么异常并没有在vb的旧版“On Error Goto X”语法之外增加很多值。
答案 4 :(得分:9)
这取决于sql
的确做什么。是它的东西:
从这些问题开始,他们通常会得到关于如何处理异常的答案
答案 5 :(得分:5)
除非你期待错误(API说它可以发生)并且可以处理它(如果发生异常,还有明显的步骤),你可能想要以大量噪声崩溃。这应该在测试/调试期间发生,以便在用户看到之前修复bug!
当然,正如评论者指出的那样,用户永远不应该真正看到所有这些噪音。高级try/catch
或其他一些方法(EMLAH,我听说.net网站项目)可以用来向用户显示一个很好的错误信息(“糟糕!出了点问题!你到底想要什么?做什么?“)用提交按钮......
所以基本上,我的观点是:不要捕捉到你不知道如何处理的错误!(除了高级处理程序)。尽早崩溃并尽可能多地提供信息。这意味着您应该记录调用堆栈以及其他重要信息(如果可能的话)。
答案 6 :(得分:2)
如果不知道如何应对,请不要捕捉异常。
在一个你有可能处理它的地方,以及你知道如何继续执行之后,把它抓住。
答案 7 :(得分:2)
要记住的一件事是,在您认为您确实想要使用try / catch的部分中,您应该将Dim语句移出try块。您可以在块内分配它们,但如果在try块中定义它们,则您将无法访问catch部分中的那些变量,因为它们将在该点之外超出范围。
我在catch块中的标准做法,包括在可能的情况下尝试修复错误,是写出我正在使用的任何日志记录机制,使用有关导致错误的部分中涉及的关键变量的信息。这没有必要,但我发现它经常有助于调试问题。
答案 8 :(得分:2)
我想告诉你,如果你不知道如何处理异常,请不要抓住它。编码人员往往会抓住异常并将其全部吞没。
catch (Exception ex)
{
/* I don't know what to do.. *gulp!* */
}
显然这不好,因为坏事正在发生,并且没有采取任何行动。只捕获可操作的异常!
尽管如此,优雅的错误处理很重要。不希望你的应用程序崩溃,对吧?您可能会发现ELMAH对Web应用程序很有用,并且可以很容易地为WinForms或XAML桌面应用程序设置全局异常处理程序。
将所有这些放在一起,您可能会发现此策略很有用:1。捕获您知道可能发生的特定异常(DivideByZeroException,SQLException等)并避开通用的catch-all Exception; 2.处理后重新引发异常。 e.g。
catch (SQLException ex)
{
/* TODO: Log the error somewhere other than the database... */
throw; // Rethrow while preserving the stack trace.
}
你对SQLException有什么用处?数据库连接是否消失了?这是一个糟糕的疑问吗?你可能不想为此添加所有处理逻辑,此外,如果它是你没想到的东西呢?所以,如果可以,只需处理异常,重新提升,除非您确定已经解决,并在全球级别优雅地处理它(例如显示消息,如“出了点问题,但你可以继续工作。详细信息:'[ex.Message]'。中止或重试?“)
HTH!
约翰桑德斯,谢谢你的纠正。答案 9 :(得分:1)
首先,如果您的应用程序无法处理异常,那么您不应该首先捕获它(logging can be done via exception event handlers without catching)。
如果有什么可以做,那就去做吧。例如,回滚事务并向用户报告失败。这取决于您的申请。
答案 10 :(得分:1)
仅供参考,您不必使用catch来获得finally语句。
有时人们会抛出一个更加友好的新异常,并将原始异常添加为内部异常。
通常用于将错误记录到文件或向运营商发送电子邮件。
有时候,特别是对于SQL,它可能只意味着一个重复的密钥,这意味着,例如,请选择另一个用户名,一个用户名已经被使用 - 这完全取决于您的应用程序。
答案 11 :(得分:0)
我会考虑记录异常发生并通知用户您无法完成他们的请求。这假定此SQL请求对于完成用户尝试执行的操作是必需的。
答案 12 :(得分:0)
完全取决于背景。可能的选项包括“使用默认数据而不是数据库中的数据”和“向用户显示错误消息”。
答案 13 :(得分:0)
如果您不想对它做任何事情,您可以随时尝试/最后尝试/ catch / finally
答案 14 :(得分:0)
根据应用程序的类型,考虑全局日志记录处理程序(即ASP.NET应用程序的“Application_Error”)或使用预构建的开源或MSFT提供的异常处理框架。
作为Enterprise Library 5.0的一部分,Exception Handling Application Block是建议使用的框架。
除了记录,我同意不需要明确捕获异常,除非你需要对它们做一些有意义的事情。而最糟糕的错误只是“捕获”然后再次“投掷”,因为这会使StackTrace混乱。
答案 15 :(得分:0)
那么, 这主要取决于您是否从您的申请中赚钱。 根据我的经验,没有人(为应用程序付费)喜欢看到它崩溃和关闭,而是他们更喜欢关于错误的简短和解释性消息,并且第二次机会继续他们正在做的事情以及保存/导出他们修改的机会数据。 IMO的最佳做法是捕获可能导致错误控制的所有内容,例如I / O操作,网络相关任务,e.t.c。并向用户显示相关消息。如果由于逻辑相关的错误而抛出异常,最好不要捕获它,因为这将帮助您找到并纠正实际错误。
希望这有帮助。