【问题标题】:Exception handling best practices in multi-tier architecture多层架构中的异常处理最佳实践
【发布时间】:2013-01-18 13:29:06
【问题描述】:

我有一个具有三轮架构的应用程序。而且我不明白如何在这种情况下处理异常。我收集了一些问题:

1 .我是否需要创建一个通用异常,例如PersistentException,并使所有 DAO 类方法只抛出一种类型的异常 - PersistentException? IE。在每个 DAO 方法 (CRUD) 中都这样做:

  public create(Entity instance) {
       try {
        ...// all operations here
       } catch(Exception e) {
          throw new PersistentException(e);
       }
    }

2 。可以为每个 EJB 服务创建一个异常类(每个EJB 接口一个异常)?

即假设我有一个 EJB bean,如 PersonManagementBeanOrganizationManagementBeanEmployeeManagementBean 以及相应的 @local@remote 接口。它们暴露给客户端,即实际上它们是会话外观(因此它们位于服务层)。所以为每个 bean 创建对应的 Exception 类是个好主意(PersonManagementException,OrganizationManagementException,EmployeeManagementException)?

或者最好只有一个名为 ServiceException 的异常(如 DAO 的情况)?

3 .哪些类型的异常会引发我的服务(忙碌)级别(在常见情况下)?我可以将 DAO (PersistentException) 异常传播给客户端吗?即

public void relocatePerson() {
   try {
      Person p = personDao.getPerson(); // can throw PersistentException
      ....
      if (someCondition) {
         throw new PersonManagementException(); // throwing same PersonManagementException
      }
      ....
   } catch(PersonManagementException e) {
       throw e; //don't need to rewrap same exception
   } catch(PersistentException e) {
       throw e; // DO I need to throw it as PersistentException to client? Or it's better to rewrap it as  PersonManagementException?
   } catch(Exception e) {
       throw new PersonManagementException(e) //throwing all exception as service specific exception
   }

}

或者我需要将所有异常(在常见情况下)重新抛出为特定于服务的异常?

  • “在一般情况下”我的意思是我知道在某些情况下,某些方法可能会抛出额外的异常并提供一些有用的信息(例如 ValidationException 提供有关哪些对象未通过验证规则的信息)

【问题讨论】:

    标签: c# java design-patterns multi-tier three-tier


    【解决方案1】:

    是的,您应该使所有 DAO 类方法只抛出一种类型的异常 - PersistentException。因为它可以帮助您将各种与数据库相关的异常捕获为一种类型。此外,您可以设置有关特定异常的消息,同时使用参数化构造函数将其设置为 PersistantException。 i.e. throw new PersistentException("Exception while opening a connection",e);

    您的第二个问题完全取决于您的要求。如果您想显示不同的错误并显示不同的错误页面并希望分别处理它们(每个 bean 的错误),那么您应该为每个 bean 创建单独的异常类。

    根据我的观点,您的第三个问题很好。您可以将 PersistentException 传播到首先调用 DAO 或 Helpers 的级别 - 即 ActionBean 或 servlet。 在那里你可以设置你的错误消息,然后你可以把它们扔给你的架构级处理程序(通常在配置或 xml 文件中配置)

    在处理异常时不要忘记“早抛晚接”

    【讨论】:

      【解决方案2】:

      对于任何表示失败的异常,只使用一个异常。理由:在这种情况下,客户端不能做任何事情,只能记录堆栈跟踪和/或向用户报告错误。

      在某些特殊情况下,您需要抛出异常以表明需要另一种方法来处理请求。 只有这些情况需要特定的例外情况

      远程客户端几乎不会想知道除了发生故障之外的任何事情;请非常小心不要给远程接口带来多余的异常类。

      【讨论】:

      • 好的,谢谢。但是你能不能更深入地解释一下这个词:be very careful not to burden your remote interface with redundant exception classes。如果我的每个远程方法都被标记为throws MyExecption 怎么办?穿什么? EJB 必须抛出什么类型的异常——已检查或未检查的异常?谢谢
      • 您声明的所有异常都必须包含在客户端 JAR 依赖项中。如果它们没有带来商业价值,它们就只是自重。由于所有 EJB 异常都必须扩展 RemoteException,因此您无法在选中和未选中之间进行选择。
      • 你确定吗?我认为扩展RemoteException(至少在EJB 3.0 中)并不是很强的要求。我有扩展Exception 的经验,而不是RemoteException
      • 我的知识来自 EJB 2.1;我欢迎这样的改变。我总是更喜欢未经检查的异常:当你需要捕获一个异常时,你会知道它没有编译器告诉你。即使您没有发现它,这也是有史以来最容易解决的错误。
      猜你喜欢
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-11
      • 2013-05-09
      • 2011-11-10
      • 1970-01-01
      • 2013-04-22
      相关资源
      最近更新 更多