DRY for Exception Wrapping

时间:2012-11-13 10:55:02

标签: 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 CustomException(Unexpected, e);
}

在每种方法中重复这一点似乎违反了DRY原则,我想知道重构它的最佳方法是什么。例如,我正在考虑一个包装方法,例如:

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

3 个答案:

答案 0 :(得分:2)

看一下AspectJ软化异常。

还要看看番石榴的Throwables。

还有Lamboks偷偷摸摸的例外。

另一种选择是使用匿名对象实例,也就是闭包。

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()

答案 1 :(得分:1)

这在Java7及以上版本中是可行的:

http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html

来自doc:

的复制粘贴示例
catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

答案 2 :(得分:0)

这是一种解决方法:

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);