Exception Groovy结束异常与引发的异常不同

Exception Groovy结束异常与引发的异常不同,exception,groovy,Exception,Groovy,我在Groovy中遇到了一个非常奇怪的行为。当我从脚本中的闭包抛出异常时,抛出的结束异常是不同的 以下是代码和详细信息: public class TestDelegate { def method(Closure closure) { closure.setResolveStrategy(Closure.DELEGATE_FIRST); closure.delegate = this; closure.call(); }

我在Groovy中遇到了一个非常奇怪的行为。当我从脚本中的闭包抛出异常时,抛出的结束异常是不同的

以下是代码和详细信息:

public class TestDelegate {

    def method(Closure closure) {
        closure.setResolveStrategy(Closure.DELEGATE_FIRST);
        closure.delegate = this;
        closure.call();
    }

    public static void main(String[] args) {
        // Make Script from File
        File dslFile = new File("src/Script.dsl");
        GroovyShell shell = new GroovyShell();
        Script dslScript = shell.parse(dslFile);

        TestDelegate myDelegate = new TestDelegate();

        dslScript.metaClass.methodMissing = {
            // will run method(closure)
            String name, arguments ->
            myDelegate.invokeMethod(name, arguments);
        }

        dslScript.metaClass.propertyMissing = {
            String name ->

            println "Will throw error now!"
            throw new MyOwnException("errrrror");
        }

        dslScript.run();
    }
}

class MyOwnException extends Exception {
    public MyOwnException(String message) {
        super(message);
    }
}
Script.dsl:

method {
    println a;
}
因此,计划是当我在
TestDelegate
中运行
main()
方法时,它将运行DSL脚本,该脚本调用方法
method()
。在脚本中找不到它,它将调用
methodMissing
,然后从
myDelegate
调用
method()
,然后调用闭包,将委托设置为
testDelegate
。到目前为止,一切顺利。然后,闭包应该尝试打印出未定义的“a”,从而引发
属性missing
,这将引发
MyOwnException

但是,当我运行代码时,我得到以下输出:

Will throw error now!
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: a for class: TestDelegate
现在,它一定已经到达了catch块,因为它打印了“现在将抛出错误!”它一定也抛出了
MyOwnException
!但是在某种程度上,
MyOwnException
被转换为
missingpropertyxception
,我不知道为什么。有人知道吗


注意:如果我从
TestDelegate\35; method()
中删除
closure.setResolveStrategy(closure.DELEGATE_FIRST)
,代码将按预期运行并抛出
MyOwnException
。但是对于我的DSL项目,我确实需要
setResolveStrategy(Closure.DELEGATE\u优先)
。我更愿意知道这一问题的根本原因,而不是仅仅删除一两行代码,然后在不了解原因的情况下查看它的工作情况。

我认为这就是本质上发生的情况:使用委托优先解析策略,Groovy运行时首先尝试访问
myDelegate
上的属性
a
,这会导致
丢失属性异常
,因为不存在此类属性。然后它尝试
属性missing
,这会导致抛出
MyOwnException
。最终,运行库放弃并重新调用遇到的第一个异常(设计决策),这恰好是
MissingPropertyException

使用所有者优先解决策略,首先咨询
propertyMissing
,因此
MyOwnException
最终被收回


查看下面的堆栈跟踪和源代码可以提供更多证据。

因此,除了先将解析策略设置为owner之外,没有其他方法可以解决此问题。根据您试图实现的目标,有不同的解决方法。例如,可以将属性missing移动到委托中。顺便说一下,实现基于脚本的DSL的一个好方法是使用自定义脚本基类。