Java 干燥后进行例外包装

Java 干燥后进行例外包装,java,exception,refactoring,Java,Exception,Refactoring,我正在编写一些服务器端代码,这些代码在将异常传递到客户端之前包装所有异常,因此所有面向客户端的方法都有以下代码 try{ DoSomething(); } catch (ExceptionA e) { throw new CustomException(AType, e); } catch (ExceptionB e) { throw new CustomException(BType, e); } catch (Exception e) { throw new Cust

我正在编写一些服务器端代码,这些代码在将异常传递到客户端之前包装所有异常,因此所有面向客户端的方法都有以下代码

try{
   DoSomething();
} catch (ExceptionA e) {
   throw new CustomException(AType, e);
} catch (ExceptionB e) {
   throw new CustomException(BType, e);
} catch (Exception e) {
   throw new CustomException(Unexpected, e);
}
在每种方法中重复这一点似乎违反了DRY原则,我想知道重构它的最佳方法是什么。例如,我正在考虑一种包装方法,例如:

private void wrapException(Exception e) {
if (e instanceof ExceptionA) {
   throw new CustomException(AType, e);
}
etc...

这是一种方法:

Exception caughtEx = null;
String extraInfo = null;
try{
   DoSomething();
} catch (ExceptionA e) {
   caughtEx = e;
   extraInfo = AType;
} catch (ExceptionB e) {
   caughtEx = e;
   extraInfo = BType;
} catch (Exception e) { // catching Exception is usually a bad idea, just let it bubble up without catching...
   caughtEx = e;
   extraInfo = Unexpected;
}
if (caughtEx != null) throw new CustomException(extraInfo, caughtEx);

看看AspectJ柔化异常

再看看番石榴的一次性饮品

还有兰博克的鬼鬼祟祟的例外

另一个选项是使用匿名对象实例,即闭包

public abstract class Wrapper {
    public void execute() { 
        try {
            // do some boiler plate before
            this.wrap();
            // do some boiler plate after.
        } catch (ExceptionA | ExceptionB ex)  {
            Type t = determineType(ex);
            throw new CustomException(t, ex);
        }
    }
    public void abstract wrap();
}
现在,在代码中,您可以执行以下操作:

new Wrapper() {
    public void wrap() {
        DoSomething();
    }
}.execute()

这在Java7及更高版本中是可能的:

从上述文档复制粘贴示例:

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

这最终将比目前更多的代码和更少的模块化。异常捕获和包装非常重要,这样就不会向客户端公开服务器端实现。@在这个简单的示例中,FooBar的代码更多,但是如果末尾的“then”块更长,或者如果它包含您不想重复的非样板代码,那么它就开始有意义了。我认为您误解了这个问题。try-catch不在单个方法中,而是在面向客户机的公共方法中。这仍然需要在每个有趣的库中都有样板文件,但它们并不真正适用于我的问题。我正在考虑重构一些样板错误捕获,最好不要使用外部库。是的,但您可以看看Throwables.propagate是如何工作的(代码方面)