当前位置:  开发笔记 > 编程语言 > 正文

如何从未经检查的异常中恢复?

如何解决《如何从未经检查的异常中恢复?》经验,为你挑选了1个好方法。

如果您想以相同的方式处理每个故障,例如通过记录它并跳到下一个请求,向用户显示消息并处理下一个事件等,如果这是我的用例,那么所有我都可以使用未经检查的异常.要做的是在我的系统中捕获一些高级别的常规异常类型,并以相同的方式处理所有内容.

但我希望从特定问题中恢复,而且我不确定使用未经检查的异常来处理它的最佳方法.这是一个具体的例子.

假设我有一个使用Struts2和Hibernate构建的Web应用程序.如果异常冒泡到我的"动作",我会记录它,并向用户显示一个非常道歉.但我的Web应用程序的一个功能是创建新的用户帐户,这需要一个唯一的用户名.如果用户选择已存在的名称,Hibernate会org.hibernate.exception.ConstraintViolationException在我的系统内容中抛出(未经检查的异常).我真的想通过要求用户选择另一个用户名来恢复这个特定问题,而不是给他们相同的"我们记录了你的问题,但现在你已经被软化了"的消息.

以下是需要考虑的几点:

    有很多人同时创建帐户.我不想在"SELECT"之间锁定整个用户表以查看名称是否存在,如果不存在则锁定"INSERT".在关系数据库的情况下,可能有一些技巧可以解决这个问题,但我真正感兴趣的是一般情况下,由于基本的竞争条件,预先检查异常将不起作用.同样的事情可能适用于在文件系统上查找文件等.

    考虑到我的首席技术官倾向于通过读取"Inc."中的技术专栏引起的偷渡管理,我需要在持久性机制周围留下一层间接,以便我可以抛弃Hibernate并使用Kodo,或者其他什么,而不会改变除了最低限度之外的任何东西.持久性代码层.事实上,我的系统中有几个这样的抽象层.尽管有未经检查的异常,我怎样才能防止它们泄漏?

    已检查异常的一个声明的弱点是必须在堆栈的每个调用中"处理"它们 - 或者通过声明调用方法抛出它们,或者通过捕获它们并处理它们.处理它们通常意味着将它们包装在另一个适合抽象级别的类型的检查异常中.因此,例如,在checked-exception中,我的UserRegistry的基于文件系统的实现可能会捕获IOException,而数据库实现会捕获SQLException,但两者都会抛出UserNotFoundException隐藏底层实现的内容.我如何利用未经检查的异常,免除每层的包装负担,而不泄漏实现细节?

Craig Walker.. 15

IMO,包装异常(检查或其他)有几个值得花费的好处:

1)它鼓励您考虑您编写的代码的失败模式.基本上,您必须考虑您调用的代码可能抛出的异常,反过来您将考虑您为调用您的代码抛出的异常.

2)它使您有机会将额外的调试信息添加到异常链中.例如,如果您有一个方法在重复的用户名上抛出异常,您可以用一个包含有关失败情况的附加信息(例如,提供欺骗用户名的请求的IP)的方法来包装该异常.低级代码无法使用.异常的cookie跟踪可以帮助您调试复杂的问题(它肯定对我而言).

3)它允许您从低级代码变为独立于实现.如果你要包装异常并需要将Hibernate替换为其他ORM,你只需要更改你的Hibernate处理代码.所有其他代码层仍将成功使用包装的异常,并将以相同的方式解释它们,即使基础环境已发生变化.请注意,即使Hibernate以某种方式发生更改,这也适用(例如:它们在新版本中切换异常); 它不仅仅是批发技术的替代品.

4)它鼓励您使用不同类别的异常来表示不同的情况.例如,当用户尝试重用用户名时可能会出现DuplicateUsernameException,而当由于数据库连接断开而无法检查重写用户名时,可能会出现DatabaseFailureException.反过来,这可以让您以灵活而强大的方式回答您的问题("我该如何恢复?").如果您收到DuplicateUsernameException,则可能决定向用户建议不同的用户名.如果您收到DatabaseFailureException,您可能会让它冒泡到用户向用户显示"向下维护"页面的位置,并向您发送通知电子邮件.一旦你有自定义异常,你就有了可定制的响应 - 这是一件好事.



1> Craig Walker..:

IMO,包装异常(检查或其他)有几个值得花费的好处:

1)它鼓励您考虑您编写的代码的失败模式.基本上,您必须考虑您调用的代码可能抛出的异常,反过来您将考虑您为调用您的代码抛出的异常.

2)它使您有机会将额外的调试信息添加到异常链中.例如,如果您有一个方法在重复的用户名上抛出异常,您可以用一个包含有关失败情况的附加信息(例如,提供欺骗用户名的请求的IP)的方法来包装该异常.低级代码无法使用.异常的cookie跟踪可以帮助您调试复杂的问题(它肯定对我而言).

3)它允许您从低级代码变为独立于实现.如果你要包装异常并需要将Hibernate替换为其他ORM,你只需要更改你的Hibernate处理代码.所有其他代码层仍将成功使用包装的异常,并将以相同的方式解释它们,即使基础环境已发生变化.请注意,即使Hibernate以某种方式发生更改,这也适用(例如:它们在新版本中切换异常); 它不仅仅是批发技术的替代品.

4)它鼓励您使用不同类别的异常来表示不同的情况.例如,当用户尝试重用用户名时可能会出现DuplicateUsernameException,而当由于数据库连接断开而无法检查重写用户名时,可能会出现DatabaseFailureException.反过来,这可以让您以灵活而强大的方式回答您的问题("我该如何恢复?").如果您收到DuplicateUsernameException,则可能决定向用户建议不同的用户名.如果您收到DatabaseFailureException,您可能会让它冒泡到用户向用户显示"向下维护"页面的位置,并向您发送通知电子邮件.一旦你有自定义异常,你就有了可定制的响应 - 这是一件好事.

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有