创建自定义exception还是使用内置exception?

目前,我正在编写一个客户端类,在其他喜欢抛出exception的类中使用DNS,套接字和SSL。 其他人将实现这个类,所以我想知道抛出exception的最佳做法是什么。

我应该创建自己的自定义exception,以便他们知道这是我的类抛出exception,还是应该允许我调用的类和方法(DNS,套接字等)抛出自己的exception? 目前,代码是数百行,并且随着许多不同的方法调用而增长。 在这种情况下抛出exception的最佳做法是什么?

如果BCL包含已传达所需含义的类(例如ArgumentNullException ),请使用这些类。

使用您自己的exception类保留特定于API的内容。

如果您认为可以添加信息,请务必提出自己的exception但不要吞下exception – 将它们作为您自己的内部exception传播。

如果添加信息,可以抛出自己的exception,但除非存在安全问题,否则不要从底层服务中吞下exception。

如果要捕获一个exception并抛出一个新exception,请将旧InnerException分配给新InnerException属性。 您可以通过这种方式嵌套尽可能多的exception,从而创建exception传播方式的分层“视图”,这对调试非常有用。

你可以做的最糟糕的事情是在消息字符串中抛出一个带有详细信息的ApplicationException。 如果您发现自己需要这样做,那么是时候进行自定义exception了。

这实际上取决于您的受众,即您class级的消费者。

例如,如果您实质上包含了许多不同的exception,那么创建自定义exception可能是一个好主意,这将简化消费者中的error handling。

如果您确实创建了自定义exception,请确保将原始exception包含在自定义exception的InnerException中,除非您明确有理由隐藏它。 这将是人们使用您的课程提供的最多信息,以及如果您的课程没有完全覆盖的例外情况,则会为您提供保险。

如果你想让任何人从你的exception中捕获并恢复,最好使用一小部分自定义exception类型,可能是由预期的可恢复性程度组织的(例如,有一个exception类型指示’意外发生的事情,但套接字很可能仍然很好’,另一个’套接字状态不能被信任,但是重新开始使用新的套接字连接可能有效’,另一个用于’主机说你正在做什么将无法工作;甚至不打扰重试除非你有理由相信某些事情发生了变化’)。 引起exception的细节通常对于“捕获”代码而言不如违反后置条件的性质重要。