我遇到了异常!怎么办?

时间:2010-04-08 12:16:53

标签: sql vb.net exception-handling

我已经开始使用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

16 个答案:

答案 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。并向用户显示相关消息。如果由于逻辑相关的错误而抛出异常,最好不要捕获它,因为这将帮助您找到并纠正实际错误。

希望这有帮助。