Vb.net 为什么捕获异常只是为了再次抛出它?
在Web服务中,我看到以下代码:Vb.net 为什么捕获异常只是为了再次抛出它?,vb.net,web-services,exception,exception-handling,Vb.net,Web Services,Exception,Exception Handling,在Web服务中,我看到以下代码: <WebMethod()> _ Public Function dosomething() As Boolean Try If successful Then Return True Else Return False End If Catch ex As Exception Throw ex End Try End
<WebMethod()> _
Public Function dosomething() As Boolean
Try
If successful Then
Return True
Else
Return False
End If
Catch ex As Exception
Throw ex
End Try
End Function
_
作为布尔值的公共函数dosomething()
尝试
如果成功的话
返回真值
其他的
返回错误
如果结束
特例
投手
结束尝试
端函数
捕获异常并再次抛出它有什么意义?我错过什么了吗
编辑:
谢谢你的回答!我以为是这样的,但不确定我是否能/会在没有任何影响的情况下重构它们。我想不出有什么理由为了功能而这样做。但是,如果以前删除了一些错误处理(通常是日志记录),并且开发人员删除了日志处理,但没有重新构造代码以删除冗余的try/catch,则可能会出现这种情况。可能是调试过程中遗留的一些代码(您已经在抛出时设置了一个断点,以便可以在调试器中检查异常)。如果我想记录异常并将其传递到链上,我可能会执行类似的操作,不过我可能会在另一个异常中封装一条更有意义的(对我的应用程序)错误消息。不要这样做。
如果您确实需要重新显示异常,只需使用
throw;
使用throw ex;
即可擦除堆栈跟踪,这是完全错误的。如果您想捕获异常的子类以外的异常,您可能需要执行此操作
比如说,
try {
// Something stupid
}
catch(RuntimeException e) {
throw e; //Handle it outside
}
catch (Exception e) {
// I'm dead
}
我所看到的其中一种架构就是处理事务的地方。函数完成工作,失败,catch块将事务完成到已知状态(通常是回滚),然后抛出一个用户定义的异常
Sub CatchAndRethrowImplicitly()
Try
ThrowException()
Catch e As ArithmeticException
' Satisfies the rule.
Throw
End Try
End Sub
现在,将代码重构到一个更合理的状态。不仅try/catch没有意义,IF也没有意义。整个函数可以简化为一行:
return successful
在这一点上,为什么要麻烦呢?为什么不直接测试“成功”而不是调用函数呢
好吧,这是一个Web方法,我想你需要这个函数只是为了给Ajax或任何人一个句柄
(是的,我知道我的答案晚了7年。我只是在搜索完全无关的东西时偶然发现了这个问题。)监视器的模式很可能会重新显示错误,因为您需要一个finally来确保监视器。调用Exit
来自微软的代码分析:(CA2200:重新浏览以保留堆栈细节) "抛出异常后,它携带的部分信息是堆栈跟踪。堆栈跟踪是方法调用层次结构的列表,该层次结构以抛出异常的方法开始,以捕获异常的方法结束。如果通过在throw语句中指定异常来重新抛出异常,则堆栈跟踪为res从当前方法开始,引发异常的原始方法和当前方法之间的方法调用列表丢失。若要保留包含异常的原始堆栈跟踪信息,请使用throw语句,但不指定异常。“
这样做有非常好的理由,尤其是在全栈/N层环境中 在类库中尝试/捕获代码、记录异常并将其返回到调用应用程序以允许调用方以其希望的方式处理异常是有意义的 请记住,在完整的堆栈环境中,堆栈应该是独立的,并且不知道彼此的内部功能,同样,它们也不应该假设知道堆栈本身以外的堆栈处理捕获的异常的方式。实时处理异常,然后将其传递给调用方是一件非常有用的事情。
总是用“扔”,而不是“扔”".Throw将重新调用句柄异常,使其堆栈保持完整。这也是为什么如果我需要进行日志记录,我会将其包装为内部异常的另一个原因。为什么?只需抛出原始异常。日志记录不应更改或更改任何内容。若要向异常添加我自己的语义。例如,由于我试图N用重复的主键插入一行。在我的方法中,我知道插入的是什么类型的对象和键值。我可以编写更好的异常消息,但仍然保留所有信息。这与日志记录无关。不同的概念。但你仍然不想调用“throw e”。你想改为“throw”。调用“throw e”将堆栈信息放到这一点上是危险的。错误。请不要告诉别人。抛出e;显然是错误的,但除此之外,这是一个有趣的想法。不确定是否有它的用例……而且你还吞下了一般异常,所以没有人知道它。@争吵:不,只是错了。There不是从中获得的智慧或知识。正是我所看到的模式
Sub CatchAndRethrowImplicitly()
Try
ThrowException()
Catch e As ArithmeticException
' Satisfies the rule.
Throw
End Try
End Sub