如何实现多个异常的包装器?

use*_*693 4 java error-handling exception

我有一些模块,每个模块都包含一些我想从持久文件中解析的模型。

当我读取文件时,我不知道哪个模块能够解析它,这就是为什么我尝试使用第一个模块的解析器来解析它。如果失败,我会尝试使用第二个模块的解析器并继续,直到尝试完所有解析器为止。解析器可以以多个异常(Exception 类的不同子类型)或解析的模型对象(ModelBase 类的不同子类型)的形式返回信息。

如果没有一个解析器成功,我想将所有给定的异常包装成一个大异常,抛出它并在我的应用程序代码中的某个位置捕获它(以新的大异常的形式),在那里我可以处理问题(例如显示所有向用户解析问题和堆栈跟踪,以某种方式处理它们等)。

我的伪代码:

ModelBase getModelOrBigException(File file)
    throws MyBigException {

    List<Exception> exceptions = new ArrayList<>();
    for (Module module : myModules){
        try {
            ModelBase model = module.parse(file);
            return model;
        } 
        catch (ParsingException1 p1) { exceptions.add(p1); }
        catch (ParsingException2 p2) { exceptions.add(p2); }
    }
    throw new MyBigException(exceptions);
}
Run Code Online (Sandbox Code Playgroud)

我想调用代码

void openFilesHandler(){

    //... selecting file 

    try {
        process(getModelOrBigException(file));
    } catch (MyBigException e) { 
        // process the sub-exceptions or show them to user or print stacktraces of all sub-exceptions or show sub-exceptions by type etc
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,如果我捕获 MyBigException,默认情况下我将无法调用 getStackTrace()、getMessage()、getLocalizedMessage() 等方法,除非我实现与此类似的异常类:

class MyBigException extends Exception {

    public MyBigException(Exception e1, Exception e2, ..., Exception eN){
        super(e1, e2, ..., eN); // This is not possible, only one argument is acceptable
    }
}
Run Code Online (Sandbox Code Playgroud)

或对此:

class MyBigException extends Exception {

    List<Exception> exceptions = new ArrayList<>();

    public MyBigException(List<Exception> exceptions){
        super(exceptions); // This is not possible, list or array of exceptions is not allowed here
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:

我应该如何创建一个新的异常类型,它可以存储多个异常并支持原始异常类的方法?当我这样做时:

myBigException.printStackTrace();
Run Code Online (Sandbox Code Playgroud)

或这个:

myBigException.getMessage();
Run Code Online (Sandbox Code Playgroud)

我想打印/获取所有存储的异常的所有堆栈跟踪。我应该将所有给定的异常传递给 super() 方法吗?

有没有比上面的解决方案更好的方法来使解析解决方案更好?

dev*_*per 5

我想打印/获取所有存储的异常的所有堆栈跟踪。我应该将所有给定的异常传递给 super() 方法吗?

如果您想打印所有堆栈跟踪或异常消息,您已经差不多完成了,您需要添加更多位,如下所述:

(1) 在里面MyBigException,创建一个构造函数MyBigException(List<Exception> exceptions, String exeptionMessage)并调用super(exeptionMessage);

(2) 重写printStackTrace()MyBigException迭代每个异常对象List<Exception>并调用。printStackTrace()

您可以参考以下代码:

MyBigException班级:

public class MyBigException extends Exception {

    private List<Exception> exceptions = new ArrayList<>();

    public MyBigException(List<Exception> exceptions, String exeptionMessages){
        //call super and pass message
        super(exeptionMessages);
        this.exceptions = exceptions;
    }

    public void printStackTrace() {
        for(Exception exception : exceptions) {
            exception.printStackTrace();
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

getModelOrBigException()代码:

ModelBase getModelOrBigException(File file)
    throws MyBigException {

    List<Exception> exceptions = new ArrayList<>();

    //Capture exception messages as well using StringBuilder
    StringBuilder exceptioMessages = new StringBuilder();
    for (Module module : myModules){
        try {
            ModelBase model = module.parse(file);
            return model;
        } 
        catch (ParsingException1 p1) { 
            exceptions.add(p1); 
            exceptioMessages.append("YOUR MESSAGE FOR ParsingException1;");
        }
        catch (ParsingException2 p2) { 
            exceptions.add(p2); 
            exceptioMessages.append("YOUR MESSAGE FOR ParsingException2;");
        }
      }
      throw new MyBigException(exceptions, exceptioMessages.toString());
    }
Run Code Online (Sandbox Code Playgroud)