java - 如何在 API 的多个方法中集中处理异常

标签 java api exception error-handling

这是一个普通的 Java 8+ 问题,没有使用任何框架。

我们正在为处理表示层和其他 Activity 的更高层生成 API。我们已经与调用者达成一致,因此他们很高兴收到我们抛出的一些特定异常。

同时,我们也在使用同一协议(protocol)下的其他 API,因此我们可以自己做一些事情并抛出异常,或者我们可以调用其他 API 抛出约定的异常。 目前,我们对调用的 API 抛出的异常不做任何处理。

事实是,我们在这个基础架构中最适合在抛出异常时处理中间 Activity ,因此我们需要同时捕获我们的异常和我们正在调用的异常所提供的异常;基本上报告问题,提高系统控制等,然后重新抛出原始异常,以便顶层保持现在的状态。

我们的 API 入口点类中有大约 300 个方法:

public void method1 (arguments for method 1) {
...
}

...

public void method300 (arguments for method 300) {
...
}

我清楚地知道我可以创建一种方法来集中异常管理中要采取的操作,例如:

public void myExceptionHandler (Exception e) {
    if (e instanceOf X) {
    } else if ...
    ...
    throw particularExceptionAccordingTheCase 
}

但我也会避免修改这 300 个方法。

知道如何在这 300 个方法中注入(inject) try-catch 以将异常发送到 myExceptionHandler 而无需在每个方法中真正添加 try-catch 吗?

非常感谢任何意见和想法!

------------ mprev0 建议后--------------------------------

我试过这种方法。它确实捕获了异常等等,但是我不能重新抛出异常:我被迫捕获它,但这违背了将异常重新发送回顶层的要求。 虽然我可以抛出错误,但我在 throw new FileNotFoundException(); 行遇到编译器错误;

public class myExceptionHandler implements Thread.UncaughtExceptionHandler {

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("gotcha!");
        if (e instanceof java.lang.Error) {
            System.out.println("AAT-CORE: Fatal Error");
            throw new java.lang.Error(e.getCause());

        } else if (e instanceof java.lang.Exception) {
            System.out.println("AAT-CORE: Exception Error");
            throw new FileNotFoundException();
        }
    }

}

有什么想法吗?

------------ 经过更多挖掘,用装饰器模式修复--------

之前的类实现不起作用,因为我无法更改方法的签名,我需要重新抛出 java.lang.Exception。

使用装饰器并在那里处理界面就可以了。 作为总结:

顶层类:

public class TopLayer {
    public static void main (String[] args) {
        MiddleLayer m = new MiddleLayer();
        m.method1();
    }
}

底层类包含​​具体的API和一些实现,唯一有趣的是它包含不受控制的java.lang.Exceptions,期望顶层来完成这项工作。但是,我们在中间工作,我们将完成这项工作:

public class MiddleLayer extends BottomLayer {

    public MiddleLayer () {
        final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler();
        Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable ex) {

                System.out.println("gotcha2!");
                // carry on with prior flow
                subclass.uncaughtException(thread, ex);
            }
        });

    }

}

这样,我可以获得 system.out 并将 java.lang.Exception 传播到顶层。

Decorator 灵感来自这里:Rethrow UncaughtExceptionHandler Exception after Logging It

欢迎补充意见!

最佳答案

您可以通过实现 java.lang.Thread.UncaughtExceptionHandler 来解决这个问题接口(interface):

public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {

    @Overrides
    public void uncaughtException(Thread t, Throwable e) {
            if (e instanceOf X) {
            } else if ...
            ...
            throw particularExceptionAccordingTheCase 
    }
}

然后将它关联到所有线程,如下所示:

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler())

这将配置异常处理程序以处理应用程序的所有线程 中所有未捕获的异常。

请注意,这仅适用于尚未在您的代码中明确处理的异常,并且如果没有为某个特定线程配置其他处理程序(也可以为某些特定线程设置未捕获的异常处理程序)。

编辑:正如@JBC 所发现的,上述方法不适用于已检查的异常,因为我们被迫在我们的uncaughtException 方法中显式捕获它们(注意我们cannot add a throws clause to an overridden method)。如果我们只想重新抛出 RuntimeException 的子类型,它会毫无问题地工作。和 Error ,如果我们想让它起作用,则需要进行一些调整 - 你可以在@JBC 的问题中找到它的解释。

关于java - 如何在 API 的多个方法中集中处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56039919/

相关文章:

windows - C++ try-catch block 不捕获硬件异常

c++ - Cimg 随机抛出 CImgIOException

java - 字体,返回默认大小

java - 有没有办法在 Java 中模拟 C++ 'friend' 概念?

Java/PayPal 集成指向错误的端点

javascript - 如何在 Node js 中返回对 REST api 的响应

java - 程序运行无异常但不显示表名

java - 安卓 Java : What happens in an AsyncTask with more than one task being operated?

c# - 如何在 ASP.Net 中设计公共(public) API?

java - 陷入 Java json 异常