Поймать исключение при загрузке файла groovy - PullRequest
2 голосов
/ 14 марта 2020

У меня есть эти 3 groovy файлы:

A. groovy:

// ...
stage("Test")
{
    throw new Exception("This script fails")
}

B. groovy:

// ...
stage("Test")
{
    // Nothing, want this to pass
}

main. groovy:

// ...
m = [:]
status = [:]
scripts = ["A", "B"]
for script in scripts
{
    m["${script}"] = 
    {
        stage("${script}")
        {
            try
            {
                 load "${script}.groovy"
                 status["${script}"] = true
            }
            catch (Exception e)
            {
                 status["${script}"] = false   
            }
        }
    }
}

parallel m

for result_iterator in status:
    print "${result_iterator.key} resulted in ${result_iterator.value}"

Приведенный выше код представляет собой набросок реального кода =) Когда я запускаю main. groovy, чтобы увидеть результаты в словаре состояния, я вижу только B. A выкинул исключение и поэтому не добавил себя в словарь. Есть ли способ, как я могу поймать исключение А как-нибудь?

1 Ответ

3 голосов
/ 14 марта 2020

Задача 1

Вас укусил способ, которым Groovy замыкает переменные, находящиеся вне их области видимости. Ссылки на script внутри замыкания получат значение script в момент запуска замыкания, которое будет последним значением из script. Таким образом, оба замыкания фактически загружают "B. groovy" , и исключение никогда не генерируется!

Исправление простое, просто создайте локальную переменную внутри l oop, которая захватывает текущее значение script:

for( script in scripts ) {
    def theScript = script
    // Now only use theScript inside of the closure!
}

Задача 2

Вы не сериализуете права записи в переменную status из потоков parallel. Это может привести к очень неприятным, трудно воспроизводимым ошибкам.

Исправление заключается в использовании Map.asSynchronized() для создания синхронизированной карты :

status = [:].asSynchronized()

Завершить 'main. groovy' fix

m = [:]
status = [:].asSynchronized()  // because multiple threads write to this variable
scripts = ["A", "B"]

for( script in scripts ) {
    def theScript = script  // Important to pass the current value into the closure!

    m[ theScript ] = {
        stage( theScript ) {
            try {
                 load "${theScript}.groovy"
                 status[ theScript ] = true
            }
            catch (Exception e) {
                 status[ theScript ] = false   
            }
        }
    }
}

parallel m

for( result_iterator in status ) {
    print "${result_iterator.key} resulted in ${result_iterator.value}"
}

Примечание: Я также удалил ненужные строковые интерполяции.

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