You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins Pipeline执行失败时如何将输出发送至Slack?

问题分析与解决方案

错误原因

你遇到的问题根源有三个:

  1. post阶段重复执行失败脚本:failure块里再次调用shResult(),导致testing.py又执行一次,而原函数里的set -e会让sh步骤在脚本返回非0退出码时直接抛出异常,中断post阶段的通知流程。
  2. 判断逻辑错误:if (shResult != 0)是把函数对象和0做比较,完全不符合预期,根本无法正确判断脚本是否失败。
  3. 未保存脚本输出:没有提前存储脚本的输出内容,导致失败时无法直接复用,只能重复执行脚本获取。

修正后的Pipeline代码

def slackChannel = "default-ops"
def slackDetails = "${env.JOB_NAME} - (<${env.BUILD_URL}|Open>)"
// 全局变量存储脚本输出和退出码,避免重复执行脚本
def scriptOutput = ""
def scriptExitCode = 0

pipeline {
    agent any

    stages {
        stage('Execute testing.py') {
            steps {
                script{
                    // 一次性获取脚本输出和退出码,避免触发异常中断流程
                    def execResult = sh(
                        script: 'python3 testing.py',
                        returnStdout: true,
                        returnStatus: true
                    )
                    scriptExitCode = execResult.returnStatus
                    scriptOutput = execResult.stdout.trim()
                    
                    echo scriptOutput
                    // 根据实际退出码设置构建状态
                    if (scriptExitCode != 0) {
                        currentBuild.result = 'FAILURE'
                    }
                }
            }
        }
    }

    post {
        success {
            slackSend(
                color: '#00FF00',
                channel: slackChannel,
                message: "SUCCESSFUL: ${slackDetails}"
            )
        }
        failure {
            slackSend(
                color: '#FF0000',
                channel: slackChannel,
                message: "FAILED: ${slackDetails}\n脚本输出:\n${scriptOutput}"
            )
        }
        aborted {
            slackSend(
                color: '#808080',
                channel: slackChannel,
                message: "ABORTED: ${slackDetails}"
            )
        }
    }
}

关键修改点

  • 新增全局变量scriptOutput和scriptExitCode,一次性存储脚本的输出内容和退出码,避免重复执行脚本。
  • 使用sh步骤的returnStdout和returnStatus参数同时获取输出和退出码,既不会因为脚本失败抛出异常中断流程,又能拿到需要的信息。
  • 移除原函数里的set -e,改用退出码判断构建状态,逻辑更清晰可控。
  • post阶段的failure块直接复用提前保存的scriptOutput,无需再次执行脚本,避免触发新的异常。

兼容旧版Jenkins的替代写法

如果你的Jenkins版本不支持同时返回stdout和returnStatus的Map格式,可以通过文件中转存储输出:

stage('Execute testing.py') {
    steps {
        script{
            // 执行脚本并把输出写入文件
            scriptExitCode = sh(
                script: 'python3 testing.py > script_output.log 2>&1',
                returnStatus: true
            )
            // 读取文件获取输出内容
            scriptOutput = readFile('script_output.log').trim()
            
            echo scriptOutput
            if (scriptExitCode != 0) {
                currentBuild.result = 'FAILURE'
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者clarkus978

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 21:55:19