2010-04-06 77 views
10

我试图找出什么异常的正确形式抛出将是我写的库。我需要处理的一个例子是将用户登录到电台。他们通过扫描徽章来做到这一点。可能的事情可能出错包括:何时使用自定义异常与现有的例外与一般例外

  • 他们的徽章被停用
  • 他们没有权限在这个车站工作
  • 扫描系统
  • 他们已经不存在的徽章登录到别处
  • 数据库中另一站下来就是
  • 内部数据库错误(有时会发生,如果徽章没有得到正确设置)

使用这个库将不得不处理这些异常的一种方式或其他应用程序。他们可能会决定只是说“错误”,或者他们可能想给用户更多有用的信息。这种情况下的最佳做法是什么?为每种可能性创建一个自定义异常?使用现有的例外?使用例外并通过原因(throw new Exception("Badge is deactivated.");)?我认为这是前两种方式的组合,在适用的情况下使用现有的例外情况,并在需要时创建新的例外情况(并在有意义的情况下对例外进行分组)。

回答

5

你有两种例外。

那些特定于您的应用程序,这是很好的,以避免任何现有的例外。

您的应用程序特定异常应简化使用您的库的人的使用案例。您的应用程序特定异常是用户可以执行的操作。第四个(徽章不存在)显然不是程序性的,但更严重。

看起来您有两个特定于应用程序的错误:面向用户的事情和管理错误。

其他是其他技术的一部分;即数据库错误。你可以 - 通常 - 忽略这些。如果数据库不可用,则该API将抛出错误,并且可以让这些数据库通过您的库发泡。

您也可以将它们“包装”为包含较低级别异常的特定于应用程序的异常。如果有很多较低级的技术,这有时会很有帮助。在你的情况下,它只是一个数据库。忽略它,让数据库错误冒泡。

7

使用异常,并传入原因(抛出新的异常(“徽章被禁用。”);)

这当然是一个不好的做法,因为它违反了例外的目的 - 不仅仅是以表示异常情况的信号,但提供区分类型级别的异常的能力,因此模块的用户可以根据异常的类型做出决定。

一般来说,这是好事,尽可能再利用标准的例外,因为他们完全可以描述你的代码实际上面临着异常情况。这是很很难给在当前情况下的提醒,因为异常往往依赖于语义(参数异常或无效操作异常(也许适合“他们的徽章被停用”的情况下,例如)。

8

我基本上同意与目前的想法

  • 使用现有的核心例外酌情:。ArgumentException的,InvalidOperationException异常等,不要试图重新利用特定于其他模块的异常使用那些有明确的,通用的目的例外,并且不要将它们用于业务规则,例如,InvalidOperationException应该表示与您的API有关的不正确的操作,而不是违反业务规则
  • 对于特定于库的异常,请创建基本异常类BadgeAuthException,并始终抛出该异常类。具体的方案应在每次获得自己的子类(BadgeDeactivatedExceptionNoPermissionsAtWorkstationException等),这样,如果他们想要的应用程序可以单独处理各个子的情况下,但他们也可以正好赶上通用BadgeAuthException如果他们不想卑躬屈膝在具体情况。
  • 不管你做什么,确保Message字段总是包含不仅仅是异常名的有用信息。
1

我认为你需要为每个你描述的坐标(实际上你可以使db和内部db错误具有相同的基本例外)有一个基本异常和一个子类型异常。关键在于最好有自己的例外情况。

1

通过扩展公共基类的细粒度异常类几乎不会出错。那样的话,需要专门抓住一些并让其他人通过的呼叫者,以及想要一起对待他们的呼叫者可以这样做。