正确的帮助方法异常抛出

时间:2013-07-26 09:48:01

标签: java exception-handling

我有像

这样的功能
class Chainable {
    public Chainable doStuff(String test) {
        return doSomething(test, true);
    }

    public Chainable doStuff(String test, String test2) {
        String toUse = test + test2;
        return doSomething(toUse, false);
    }

    private Chainable doSomething(String test, boolean version) {
        // do something
        if (somethingBadHappened) {
            throw SpecialException.generate();
        }

        return this;
    }
}

SpecialException是用户应该看到的异常。异常消息故意包含抛出此异常的方法。用户将致电doSomething("x"),如果失败,则会显示"Method 'doSomething' failed with the parameters: 'test = x | version = true'"

但是用户并不关心方法doSomething(String, boolean)及其参数。他使用doStuff(String)并希望看到该功能的消息。

所以我所做的是:

public Chainable doStuff(String test) {
    try {
        return doSomething(test, true);
    } catch (SpecialException e) {
        throw SpecialException.generate(e);
    }
}

将e设置为新异常的原因并正确显示"Method 'doStuff' failed with the parameters: 'test = x'"(用户没有看到堆栈跟踪,但如果我需要调试,我可以看到究竟发生了什么)。

现在,它有效,但每次我编写一个将其工作委托给辅助函数的新函数时,我都要重复自己。问题是,我不知道应该如何使用辅助函数,因为SpecialException根据生成的位置找到方法名称...

还有另一种更好的方法吗?

2 个答案:

答案 0 :(得分:0)

以下是您应该做的事情:向用户显示堆栈跟踪。然后你可以使用

throw new SpecialException();

不关心会出现什么方法。

答案 1 :(得分:0)

据我所知,据我所知,使用aspect-oriented programming或AOP处理这种情况可能会很好。在Java中,您可以使用AspectJ

首先定义"pointcut" - 代码执行中的特定时刻,例如方法调用。接下来,您将编写一个"advice",这是切入点切割时需要完成的事情。您将这两者放在一个"aspect"中,并在构建期间将它们weaven放入字节码中。

在这种情况下,您需要一个切入点来拦截Chainable上对公共方法的调用,但不应在Chainable内进行调用:

pointcut publicChainableMethod()      :    target(Chainable)
                                        && call(public * *(..))
pointcut firstPublicChainableMethod() :    target(Chainable)
                                        && call(* *(..))
                                        && !cflowbelow(publicChainableMethod());

第一个切入点定义了对Chainable上的公共方法的任何调用,第二个切入点定义了对Chainable内的方法的调用,除了在第一个切入点的控制流程中不应该调用它。

接下来,您需要一个为您生成新SpecialException的建议:

after() throwing (SpecialException e): firstPublicChainableMethod() {
    throw SpecialException.generate(e);
}

免责声明:我不是AOP或AspectJ专家,所以这种方法可能无法开箱即用。