在什么情况下人们应该“尝试……抓住”?这适用于图书馆吗?
假设您正在设计一个应用程序(WebApp、桌面等等),并且需要为代码定义异常处理。既然你想让东西可重用,那么处理异常时应该遵循什么逻辑?有什么模式可以遵循吗?
例如,如果某个 DLL 将要使用网络并且网络不可靠,那么重写该函数的异常处理程序以重试请求可能是明智的做法。
开发人员如何处理开发所有常见方面的异常?有什么模式或模板可以遵循吗?
在处理诸如网络、文件、IO、Active Directory 和 Web 等事务时,我确信存在关于如何处理当今最常见和有问题的问题的预设最佳实践。他们位于哪里?
Suppose you're designing an application (WebApp, Desktop, anything) and you need to define exception handling for the code. Since you want to make things reusable, what logic should you follow when handling exceptions? Are there any patterns to follow?
For example, if some DLL is going to use the network and the network is unreliable, then it may be wise to override the exception handler for that function to retry the request.
How does a developer approach handling exceptions for all the common aspects of development? Is there any pattern or template to follow?
When dealing with things such as Network, File, IO, Active Directory, and the Web, I'm sure there are a pre-set best practices on how to handle the most common and problematic issues today. Where are they located?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一般来说:
针对异常情况抛出异常。
如果有意义的话,处理异常。如果您无法处理异常,请允许其向上迁移调用堆栈。
.NET 等框架的文档通常描述特定方法调用可能引发的异常。
Generally speaking:
Throw an exception for exceptional conditions.
Handle an exception if it makes sense to do so. If you can't handle the exception, allow it to migrate up the call stack.
The documentation for frameworks such as .NET usually describe the exceptions that can be thrown for a particular method call.
你回答了你自己的问题。任何可能发生超出应用程序控制/范围的错误的地方,明智的做法是进行错误处理。你永远不会有太多的错误处理。只要确保您没有因异常而编码即可。
You answered your own question. Anywhere that there is a possibility of an error occurring that is out of the control/scope of your application, it's wise to place error handling around. You can never have too much error handling. Just ensure you're not coding by exception.
调试时异常很有帮助。如果可能的话应该避免它们,因为你应该知道你的控制流程。
Exceptions are helpful when debugging. They should be avoided if possible, because you should know your control flow.
抛出异常自然应该只在特殊情况下进行。
对于处理,我想说,当您想要捕获异常时,有两种情况:
需要进行翻译时
在模块边界
如果您发现自己在做 try-catch-cleanup-rethrow 之类的事情,请改用 RAII 并完全摆脱 try...catch。编写代码,以便在发生异常时,它能以正常的方式运行。请查阅《亚伯拉罕保证》,了解有关具体内容的详细信息。
下面是对 MakerOfThings7 的回答,因为评论太长了。
我所说的“用户可以理解的东西”是指弹出的错误消息。
想象一下,如果您愿意,用户单击应用程序 UI 上的按钮即可检索一些数据。您的按钮单击处理程序会分派到某些数据存储接口。该接口可以从内存流、文件、数据库获取数据。谁知道?反过来,这些可能会失败,生成 MemoryStreamException、FileException 或 DatabaseException。这些可能已被抛出 15 个堆栈帧,并被编写良好的异常安全代码正确忽略,而无需转换它们。
按钮单击处理程序对这些一无所知,因为数据存储接口可用的数据存储方法正在不断扩大。因此,数据存储接口捕获这些异常,并将它们翻译为通用的DataStorageException。这是抛出的。
然后,调用数据存储接口的按钮单击处理程序捕获此异常,并有足够的信息能够向用户显示某种失败消息,将异常转换为一些格式良好的文本,并呈现它。
Throwing an exception should naturally only be done in an exceptional situation.
For handling, I would say that there are two circumstances when you want to catch an exception:
when there is a translation to be done
at a module boundary
If you find yourself doing a try-catch-cleanup-rethrow kind of thing, use RAII instead and get rid of the try...catch entirely. Write your code so that, if an exception does occur, it acts in a sane manner. Look up the Abrahams Guarantees for details on what that entails.
An answer to MakerOfThings7 below, because it was too long for a comment.
By "Something the user can understand," I mean for example a pop-up error message.
Imagine, if you will, the user clicks on a button on your application's UI to go and retrieve some data. Your button click handler dispatches to some data storage interface. This interface could get the data from a memory stream, from a file, from a database. Who knows? In turn, these could fail, generating a MemoryStreamException, a FileException, or a DatabaseException. These might have been thrown 15 stack frames down and been correctly ignored by well-written exception-safe code that didn't need to translate them.
The button click handler knows nothing of these, because there is an expanding army of data storage methods available to the data storage interface. So the data storage interface catches these exceptions, and translates them into a general purpose DataStorageException. This is thrown.
Then, the button click handler that called the data storage interface catches this exception, and has enough information to be able to display some kind of failure message to the user, translates the exception into some nicely formatted text and presents it.
一般规则是捕获通用异常并生成特定于域的异常。 API 还具有调试模式,以便您记录每个异常,并可以对其进行调试以用于将来的版本。
当然,这需要良好的调试,因为您不想生成不相关的异常。
只是我的两分钱:)。
The general rule is capture generic exceptions and generate domain-specific exceptions. Also have a debugging mode for the API so you log every exception and you can debug it for future releases.
Of course this requires good debugging as you dont want to generate unrelated exceptions.
Just my two cents :).