我保持简单。
库具有从std ::: runtime_error扩展的基本异常类型(来自C ++,适用于其他语言)。这个异常需要一个消息字符串,所以我们可以登录;每个抛出点都有一个唯一的消息(通常具有唯一的ID)。
就是这样
注意1:在有人捕获到异常的情况下,可以修复异常并重新启动操作。对于可能可以唯一地固定在远程位置的事物,我将添加派生异常。但这是非常非常罕见的(记住捕手不太可能接近投掷点,因此解决问题将很困难(但一切都取决于情况))。
注2:有时库是如此简单,以至于不值得给它自己的异常,而std :: runtime_error会这样做。只有将异常与std :: runtime_error区别开来的能力可以为用户提供足够的信息来对其进行处理的情况下,异常才重要。
注3:在一个类中,我通常更喜欢错误代码(但是这些错误代码永远不会在我的类的公共API中转义)。
权衡一下:
我看到的权衡包括:
更多的异常类可以为API用户提供非常精细的错误处理级别(容易发生用户配置或数据错误,或者找不到文件)
是否有更多例外确实可以使您更好地控制谷物?问题就变成了捕获的代码是否可以基于异常真正地修复错误。我确信在某些情况下,在这种情况下,您应该有另一个例外。但是,上面列出的所有例外,唯一有用的更正是生成一个大警告并停止该应用程序。
更多的异常类允许将特定于错误的信息嵌入到异常中,而不仅仅是字符串消息或错误代码
这是使用异常的重要原因。但是信息对于缓存它的人必须是有用的。他们可以使用该信息执行某些纠正措施吗?如果对象在您的库内部,并且不能用于影响任何API,则该信息将无用。您需要非常具体地说明所抛出的信息对于可以抓住它的人具有有用的价值。捕获该信息的人通常不在您的公共API范围内,因此请对您的信息进行定制,以使其可以与您的公共API中的内容一起使用。
如果他们所能做的只是记录异常,那么最好只抛出一条错误消息,而不是大量数据。由于捕获程序通常会使用数据生成错误消息。如果您生成错误消息,那么它将在所有捕获程序中保持一致,如果允许捕获程序生成错误消息,则根据谁在调用和捕获消息,您可能会得到不同报告的相同错误。
更少的异常,但是嵌入了可以用作查找的错误代码
您必须确定天气错误代码可以有意义地使用。如果可以,那么您应该有自己的例外。否则,您的用户现在需要在catch内实现switch语句(这使catch自动处理内容的整个观点变得无效)。
如果不能,那么为什么不在异常中使用错误消息(无需拆分代码和消息,这会使查找变得很麻烦)。
直接从函数返回错误代码和标志(有时无法从线程返回)
在内部返回错误代码非常有用。它允许您在那里修复错误,然后必须确保修复所有错误代码并解决它们。但是,通过公共API泄漏它们是一个坏主意。问题是程序员经常忘记检查错误状态(至少作为例外,未经检查的错误将迫使应用程序退出未处理的错误,通常会破坏您的所有数据)。
发生错误时实施事件或回调系统(避免堆栈展开)
此方法通常与其他错误处理机制结合使用(而不是替代方法)。想想您的Windows程序。用户通过选择菜单项来启动动作。这将在事件队列上生成一个动作。事件队列最终分配一个线程来处理该操作。该线程应该处理该操作,并最终返回到线程池并等待另一个任务。在这里,必须由任务执行的线程在基础处捕获异常。捕获异常的结果通常会导致为主循环生成一个事件,最终将导致向用户显示错误消息。
但是,除非面对异常可以继续进行,否则堆栈即将解散(至少对于线程而言)。