Exception 异常处理反模式

Exception 异常处理反模式,exception,exception-handling,Exception,Exception Handling,异常处理对于新手和经验丰富的开发人员来说都是一个挑战。在C++中,有哪些异常处理反模式的例子? catch(…)>代码> 可能是使代码看起来稳定的最糟糕的方法 这同样适用于任何其他语言,在这些语言中,您捕获到您不希望出现的异常,然后默默地接受它们,以便向用户隐藏错误。但是,(…)通常用于捕获异常,例如空指针取消引用或访问拒绝,这意味着被吞没的错误可能会在以后以与问题根源完全无关的方式表现出来。糟糕的清除逻辑 从析构函数抛出清理代码。这一个是双重的坏,因为a.)从析构函数抛出通常是坏的,b.)因

异常处理对于新手和经验丰富的开发人员来说都是一个挑战。在C++中,有哪些异常处理反模式的例子?

<代码> catch(…)>代码> 可能是使代码看起来稳定的最糟糕的方法

这同样适用于任何其他语言,在这些语言中,您捕获到您不希望出现的异常,然后默默地接受它们,以便向用户隐藏错误。但是,
(…)
通常用于捕获异常,例如空指针取消引用或访问拒绝,这意味着被吞没的错误可能会在以后以与问题根源完全无关的方式表现出来。

糟糕的清除逻辑

从析构函数抛出清理代码。这一个是双重的坏,因为a.)从析构函数抛出通常是坏的,b.)因为即使你能抓住它,也没有什么可以做的

File::~File()
{
    if (!close(fd_)) {
        throw FileIOException("Could not close descriptor.", fd_);
    }
}
来自地狱的UI

无退避地重试


我最讨厌的是建立一个异常继承层次结构,在这个层次结构中,后代关系对是否应该捕获异常几乎没有影响。对于预定义的异常,我们没有做太多的工作,但是我的偏好是避免抛出这些异常,而是在调用方应该假设系统状态良好的情况下定义新的异常,除非例程没有成功返回,而不是系统状态被破坏的情况下。例如,如果一个方法应该打开一个文件并返回一个新的文档对象,但是解析该文件时出现了一些问题,那么它不应该杀死整个应用程序。它应该让用户知道无法打开该文件,然后继续操作,就像用户没有尝试打开该文件一样。文件为什么没有打开是无关紧要的;问题是应用程序状态是否已损坏。不幸的是,没有一个标准的异常非常擅长处理这个问题。

这里有一个与我以前见过的情况并不完全不同

try {
    methodThatThrowsSomeException1();
    methodThatThrowsSomeOtherException2();
    methodThatThrowsSomeOtherException3();
    methodThatThrowsSomeOtherException4();
    methodThatThrowsSomeOtherException5();
    methodThatThrowsSomeOtherException6();
    ...
    methodThatThrowsYetAnotherException20();
} catch (Throwable e) {
    log.error("There was a problem reading the user role");
    role = PRIVILEGED;
}

在共享库中使用异常,这些异常是指从多语言/ C++方言中使用的。由于C++编译器无法保证你不会意外地将异常返回给调用者(与爪哇不同),你只是在为崩溃而设置自己。

不退避重试会将性能问题转化为可用性问题。很好。也许这是因为无法打开文件不是一个真正的例外事件?“这不应该是常规错误处理的一部分吗?”镇静的外星人:有时应该是例外,有时不是;这就是Try/Do模式的用途。然而,在解析例程中,通常会使用异常中止不成功的解析,而不是测试每个子操作是否成功。错误检查几乎是解析例程长度的两倍,这种情况并不少见;如果错误检查只会中止解析,那么使用异常实际上可以将代码大小减半。
 bool has_connected = false;
 while (!has_connected) {
     try {
        EstablishConnection();
        has_connected = true;
     } catch (...) {
        // IGNORE
     }
  }
try {
    methodThatThrowsSomeException1();
    methodThatThrowsSomeOtherException2();
    methodThatThrowsSomeOtherException3();
    methodThatThrowsSomeOtherException4();
    methodThatThrowsSomeOtherException5();
    methodThatThrowsSomeOtherException6();
    ...
    methodThatThrowsYetAnotherException20();
} catch (Throwable e) {
    log.error("There was a problem reading the user role");
    role = PRIVILEGED;
}