我遇到了异常!怎么办?

iam*_*esy 69 sql vb.net exception

我已经开始使用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
Run Code Online (Sandbox Code Playgroud)

小智 64

异常处理的经验法则 - 如果您不知道如何处理它,请不要捕获它.

对于异常处理的经验法则的计算 - 在最后一个负责的时刻处理异常.如果你不知道这是否是最后一个负责任的时刻,那就不是.

  • 然后我想我们都对彼此的说法感到困惑.再次阅读你的答案.如果您不知道如何处理异常,请不要抓住它.因此,您的数据库可能会抛出更新异常,原因有一百万 - 您说如果您不知道如何处理该异常,则不应该抓住它.没有比这更糟的了.想象一下,如果它引发了一个sql异常,因为你的反病毒正在阻止它,这是你从未预料到的.您应该捕获异常并显示它,让它们继续,不要忽略它并让程序崩溃和刻录. (4认同)
  • 你好reddit.感谢所有代表对这种轻率的回答.今天,我的答案会略有不同; 我还要包括一个推论:在最后一个负责任的时刻处理异常.如果你不知道这是否是最后一个负责任的时刻,那就不是. (4认同)
  • 我不同意这一点,并编辑了我的答案以反映原因. (2认同)
  • @SLC - 我和我已经解释了原因.如果你不能在生成它的情况下做一些有用的事情,那么就没有理由把它捕获到那里.这是一个设计问题.图书馆是一个很好的例子.当然,如果你有异常冒泡到顶部没有AppDomain.UnhandledException处理程序那么你完全有另一个问题.请注意,SLC,我不建议忽略异常. (2认同)
  • 硬盘或网络延迟,如果您正在捕获异常,则无论如何都为时已晚.让该死的东西冒出调用堆栈并处理应用程序顶层的奇怪系统故障. (2认同)

Nib*_*Pig 23

你想要它做什么?这完全取决于您的应用程序.

你可以让它重试,你可以在屏幕上显示一个消息框,写入日志,可能性是无穷无尽的.

作为开发人员,您无法预测每个可能的错误.即使您不知道如何修复错误,也可以使用通用捕获代码.您可能正在保存到数据库,并且可能会发生50个数据库错误之一,并且您将无法编写代码来处理每个错误.

你应该放入一个通用的catch来确保你的程序不会简单地崩溃,并且在某些情况下只是显示错误并让他们再次进行就足够了.想象一下,如果原因是"磁盘已满".您只能打印出异常,让用户再试一次 - 他们知道该怎么做,并自己解决问题.

这就是为什么我不同意如果你不知道该怎么做就不处理它的评论.您应该始终处理它,即使它只是显示一个消息框说"错误",因为它比"此程序执行了非法操作并将被关闭"无限好.

  • "你应该总是处理[例外]".我不能不同意你的意见.许多语言为无法处理的异常提供了最后机会.在最后一步,您可以使用无法处理或不知道如何处理的异常并向用户显示一个很好的"你是F-ed"对话框. (13认同)
  • @SLC意味着您可以通过添加**一个**单一通用异常处理程序来防止程序崩溃:您不需要在**每个例程**中放置异常处理**.查看文档http://msdn.microsoft.com/en-us/library/system.windows.forms.application.setunhandledexceptionmode.aspx (3认同)

Col*_*ard 20

这取决于您的业务逻辑,但您可能希望执行以下一项或多项操作.

  • 回滚您的交易
  • 记录错误
  • 提醒应用程序的任何用户
  • 重试该操作
  • 重新抛出异常

您可能还希望检查异常是否属于上述某种类型之前可以处理的类型.

一篇关于VB.NET异常处理的好文章是Rajesh VS 在VB.NET中异常处理.


Joe*_*orn 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
Run Code Online (Sandbox Code Playgroud)

不仅没有Try/Catch /最后,没有开放或关闭..Fill()函数被记录为在需要时打开连接,并且即使抛出异常,Using块也会确保它被正确关闭.

这使您可以自由地捕获更高级别的异常 - 在UI或业务代码中调用运行查询的函数,而不是在查询本身.这个更高级别的代码可以更好地决定如何继续,需要发生什么日志记录,或向用户显示更好的错误消息.

事实上,正是这种异常的能力在你的代码中"冒泡",使它们变得如此有价值.如果你总是在抛出异常的地方捕获异常,那么异常并没有在vb的旧"On Error Goto X"语法之外增加很多值.


lau*_*ura 9

这取决于SQL真正做到了什么.是这样的:

  • 用户做了什么?也许创建一个帐户或一条消息 - 然后你需要通知用户出现了问题
  • 该应用程序自然吗?喜欢清理日志或类似的东西?这是致命的吗?应用程序可以继续吗?这是可以忽略的事情 - 也许是重试的?是否应该宣布管理员?

从这些问题开始,他们通常会得到关于如何处理异常的答案


Dar*_*mas 5

除非你期望错误(API说它可以发生)并且可以处理它(如果发生异常,有一个明显的步骤),你可能想要崩溃很多噪音.这应该在测试/调试期间发生,以便在用户看到之前修复bug!

当然,正如评论者指出的那样,用户永远不应该真正看到所有这些噪音.高级别try/catch或其他方法(EMLAH,我听说.net网站项目)可以用来向用户显示一个很好的错误消息("糟糕!出了点问题!你到底想做什么?")提交按钮......

所以基本上,我的观点是:不要抓错,你不知道如何处理!(除了高级处理程序).尽早崩溃并尽可能多地提供信息.这意味着您应该记录调用堆栈和其他重要信息(如果可能的话)进行调试.

  • 最好显示一个自定义页面,"请告诉我们你在做什么"文本框和提交按钮,这样他们就可以发泄.当然,不要把它搞砸了. (4认同)
  • 另一方面,在用户眼前永远不要"碰到很多噪音".说"Ops,出了点问题,我们正在研究它." 没有公开细节. (3认同)