Groovy retry()与catchError()使用问题:Jenkins Terraform部署重试失效
问题原因
你的代码里catchError是核心问题:它默认会捕获sh命令的错误,将步骤标记为失败但不会抛出异常。而Jenkins的retry逻辑只有当块内代码抛出未被捕获的异常时,才会触发重试。所以catchError吃掉了错误,retry感知不到失败,自然不会执行重试流程,直接让流水线报错退出。
修复方案
有两种常见的修正方式,根据你的需求选择:
方案一:移除catchError(最简方式)
直接去掉catchError,让sh命令的错误直接抛出,触发retry的重试逻辑。当某次terraform apply成功时,会正常退出retry块;失败则自动重试,直到达到最大次数。
修正后的代码:
stage("Terraform apply") { steps { script { def maxRetries = 10 def retryCount = 0 dir('dev/xo/clusters/sandbox') { withCredentials([string(credentialsId: 'XOA_PASSWORD', variable: 'xoaPassword')]){ retry(maxRetries) { retryCount++ echo "Terraform apply. Attempt $retryCount of $maxRetries" // 移除catchError,让错误直接抛出触发重试 sh ''' export XOA_PASSWORD="${xoaPassword}" terraform apply -parallelism=1 -no-color "theplan" ''' } } } } } }
方案二:保留catchError并强制抛出异常
如果需要保留错误捕获的同时触发重试,可以给catchError添加参数,让它标记失败后主动抛出异常,让retry感知到错误:
stage("Terraform apply") { steps { script { def maxRetries = 10 def retryCount = 0 dir('dev/xo/clusters/sandbox') { withCredentials([string(credentialsId: 'XOA_PASSWORD', variable: 'xoaPassword')]){ retry(maxRetries) { retryCount++ echo "Terraform apply. Attempt $retryCount of $maxRetries" // 配置catchError抛出异常,触发retry catchError(buildResult: 'FAILURE', stageResult: 'FAILURE', throwException: true) { sh ''' export XOA_PASSWORD="${xoaPassword}" terraform apply -parallelism=1 -no-color "theplan" ''' } } } } } } }
额外建议
由于XO资源受限,每次terraform apply失败后可能遗留不一致的资源状态,建议在重试前添加terraform refresh同步状态,减少后续重试的失败概率:
sh ''' export XOA_PASSWORD="${xoaPassword}" terraform refresh terraform apply -parallelism=1 -no-color "theplan" '''
内容的提问来源于stack exchange,提问作者Red Cricket
相关产品推荐
相关产品推荐

