Errorlevel returned as exit code when executing bat step

Article ID:4413625628827
2 minute readKnowledge base

Issue

  • After upgrading the Durable Task plugin to version 1.37 or later and Pipeline: Nodes and Processes plugin to version 2.40 or later, builds which are executing bat steps are failing when the executed script ends up with some error code.

Explanation

Script failures were not handled before Durable Task plugin version 1.37 and Pipeline: Nodes and Processes plugin version 2.40.

When using returnStatus: true, callers are expected to handle any non zero return code themselves, so the pipeline is not failing at this point.

pipeline {
    agent { label 'windows'}

    stages {
        stage('Bat stage') {
            steps {
                script {
                    BATCH_COMMAND="""@echo off
                    fail
                    Echo ERRORLEVEL = %errorlevel%
                    """
                    batExit = bat returnStatus: true,
                    label: 'Test Exit Code',
                    script: """
                    ${BATCH_COMMAND}
                    """
                    echo "batExit = " + batExit
                }
            }
        }
    }
}
build ok

When using returnStatus: false (false is the default value when returnStatus is not used) the error is not handled by the caller so it is propagated up making the build fail.

pipeline {
    agent { label 'windows'}

    stages {
        stage('Bat stage') {
            steps {
                script {
                    BATCH_COMMAND="""@echo off
                    fail
                    Echo ERRORLEVEL = %errorlevel%
                    """
                    batExit = bat returnStatus: false,
                    label: 'Test Exit Code',
                    script: """
                    ${BATCH_COMMAND}
                    """
                    echo "batExit = " + batExit
                }
            }
        }
    }
}
build ko

Resolution

When using returnStatus: false (false is the default value when returnStatus is not used) the error should be manually handled. For example it could be handled using [try/catch] blocks (https://www.jenkins.io/doc/book/pipeline/syntax/#flow-control) as follows:

pipeline {
    agent { label 'windows'}

    stages {
        stage('Bat stage') {
            steps {
                script {
                    BATCH_COMMAND="""@echo off
                    fail
                    Echo ERRORLEVEL = %errorlevel%
                    """
                    try {
                        batExit = bat returnStatus: false,
                        label: 'Test Exit Code',
                        script: """
                        ${BATCH_COMMAND}
                        """
                    } catch (Exception e){
                        // sample code
                        echo e.toString()
                        // other code used to correctly handle the execption
                    }
                }
            }
        }
    }
}
build ok handled