自从微软推出应用程序块以来,我一直在碰到使用异常处理应用程序块的人.我最近对自己进行了仔细研究,并总结了如下基本功能(如果您已经知道它的作用,请跳过以下块):
异常处理应用程序块旨在集中并使配置文件完全配置以下关键异常处理任务:
记录异常
替换例外
包装例外
传播例外
等等
该库通过修改try catch块来实现,如下所示:
try { // Run code. } catch(DataAccessException ex) { bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy"); if (rethrow) { throw; } }根据app.config中为策略名称指定的内容(请参阅此处的文档),HandleException将...
抛出一个全新的异常(替换原来的异常)
将原始异常包装在一个新异常中并抛出它
吞下异常(即什么都不做)
你有没有重新抛出原来的例外
此外,您还可以将其配置为预先执行更多操作(例如,记录异常).
现在这是我的问题:我完全没有看到如何替换,包装,吞下或重新抛出异常使其可配置是多么有益.根据我的经验,这个决定必须在您编写代码时做出,因为在更改异常处理行为时,您通常必须更改周围或调用代码.
例如,当您重新配置时,您的代码可能会开始行为不正确,以至于现在吞下特定点抛出的特定异常而不是重新抛出(可能在发生异常时不能执行catch块之后的代码).对于异常处理中的所有其他可能的更改也是如此(例如,替换 - >重新抛出,吞下 - >换行).
所以,对我来说,底线是异常处理块解决了实际上根本不存在的问题.异常记录和通知位很好,但是并非所有其他东西都只是过度工程的完美示例吗?
如果您使用控制流的异常,那么您可能希望远离基于策略的异常处理.
但是,如果您希望将异常视为不可恢复(后台任务失败,套接字断开,文件被删除等),您可能希望具有可配置的基于策略的异常处理.
例如,如果您正在开发API,您可能希望API中的每个函数仅抛出标准异常(ArgumentException
等等),以及在内部非标准异常的情况下您自己的库特定异常(例如a MyLibraryException
).在这种情况下,重要的是某些东西不能正常工作.你没有挑选异常并弄清楚出了什么问题.你只是承认一个事实,即有些事情出了错,那你应该做一些事情了.
这一些东西应该是可配置的,因为它并没有真正不管你做什么.向用户显示消息框?模态还是非模态?记录异常?你想如何记录异常?调用日志Web服务?附加到日志文件?写入Windows事件日志?在数据库中插入一个条目?在两个数据库中插入一个条目?它对你的其他应用程序来说并不重要.如何处理异常的选择与应用程序的其余部分完全正交.
(顺便说一句,这不是我如何处理可配置的基于策略的异常处理.我倾向于更倾向于AOP样式,例如在容器中注册异常记录器拦截器.)
当我开发没有可恢复状态的函数时,我遇到了这个问题.我相信这种策略驱动的异常处理实际上很有用,并确保属于该项目的所有其他开发人员实际上遵守不可恢复异常的标准.
我同意上面的海报,如果您将它们用于控制流程,您可能希望远离基于策略的异常.