Groovy конец исключения отличается от исключения - PullRequest
0 голосов
/ 18 августа 2011

Я сталкиваюсь с чрезвычайно странным поведением в 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;
}

Таким образом, план состоит в том, что когда я запускаю метод main() в TestDelegate, он запускает сценарий DSL, который вызывает метод method(). Не найдя его в скрипте, он вызовет methodMissing, который затем вызовет method() из myDelegate, что, в свою очередь, вызовет замыкание, установив делегату значение testDelegate. Все идет нормально. Затем предполагается, что замыкание попытается распечатать «a», которое не определено, и, таким образом, будет установлено значение propertyMissing, которое выдаст MyOwnException.

Однако, когда я запускаю код, я получаю следующий вывод:

Will throw error now!
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: a for class: TestDelegate

Теперь он, должно быть, достиг этого блока catch, поскольку на нем было напечатано "Будет выдано сообщение об ошибке!" Должно быть, выбросил MyOwnException тоже! Но где-то вдоль линии MyOwnException был преобразован в MissingPropertyException, и я понятия не имею, почему. У кого-нибудь есть идеи?

P.S. если я удаляю closure.setResolveStrategy(Closure.DELEGATE_FIRST) из TestDelegate#method(), код работает как положено и выдает MyOwnException. Но мне действительно нужен setResolveStrategy(Closure.DELEGATE_FIRST) для моего проекта DSL. И я бы предпочел узнать причину этого, а не просто удалить строку или две, и увидеть, что это работает, не понимая, почему.

1 Ответ

1 голос
/ 20 августа 2011

Я думаю, что это то, что по существу происходит: при стратегии разрешения в первую очередь, среда исполнения Groovy сначала пытается получить доступ к свойству a в myDelegate, что приводит к MissingPropertyException, поскольку такого свойства не существует. Затем он пытается propertyMissing, что приводит к выбрасыванию MyOwnException. В конце концов среда выполнения сдает и отбрасывает первое возникшее исключение (проектное решение), которое оказывается MissingPropertyException.

При стратегии решения «сначала владелец» сначала обращаются к propertyMissing, и, следовательно, MyOwnException в конечном итоге отбрасывается.

Просмотр трассировки стека и исходного кода под ним должен предоставить больше доказательств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...