如何在Jenkins任务的catch块中区分任务失败与用户中止?
区分Jenkins构建失败与用户中止的方法
我之前也踩过这个坑!确实用err.getMessage()、err.getCause()或者直接看currentBuild.result很难稳定区分这两种场景,不过有两个比较靠谱的方案可以解决:
方案1:通过异常类型精准判断
当用户手动中止Jenkins流水线时,抛出的异常通常是org.jenkinsci.plugins.workflow.steps.FlowInterruptedException,而普通的构建失败(比如脚本错误、任务执行异常)会抛出其他类型的异常。我们可以利用这一点在catch块里做区分:
try { // 执行你的工作内容 echo "执行任务中..." } catch (err) { // 先判断是否是中止类异常 if (err instanceof org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) { def abortCause = err.getCause() // 进一步判断是否是用户触发的中止 if (abortCause instanceof hudson.model.Cause.UserIdCause) { echo "构建被用户 ${abortCause.getUserId()} 手动中止了" } else { echo "构建被系统(比如超时、资源不足)中止了" } } else { echo "构建执行失败,异常详情:${err.toString()}" } }
方案2:通过构建原因列表判断
Jenkins会记录构建的触发/中止原因,我们可以通过currentBuild.getBuildCauses()来检查是否存在用户中止的记录:
try { // 执行你的工作内容 echo "执行任务中..." } catch (err) { def isUserAborted = currentBuild.getBuildCauses().any { cause -> cause.shortDescription.contains("Aborted by") || cause.class.name == "hudson.model.Cause.UserIdCause" } if (isUserAborted) { echo "构建被用户手动中止" } else { echo "构建执行失败" } }
为什么你之前的方法不稳定?
err.getMessage()和err.toString()的输出内容会随异常类型、Jenkins版本变化,没有固定格式,无法可靠判断。currentBuild.result在catch块执行时可能还未被Jenkins系统最终设置(流水线的结果通常在整个流程结束后才会更新),所以获取到的值可能不准确。
我在Jenkins 2.300+的版本上测试过这两种方案,都能稳定区分两种场景,你可以根据自己的Jenkins版本调整类名(比如旧版本可能用hudson.model.Cause.UserCause替代UserIdCause)。
内容的提问来源于stack exchange,提问作者PortMan
相关产品推荐
相关产品推荐

