Search code examples
jenkinsgroovyjenkins-pipeline

Get output bat in Jenkins Declarative Pipeline if return status is error


I'm trying to get the output of a bat script regardless of the return status.

String spectralOutput
try {
  spectralOutput = bat(script: '''
    @spectral lint "%WORKSPACE%\\SelfContained\\*.json" --ruleset "%WORKSPACE%\\spectral\\.spectral.json"
    ''', returnStdout: true, encoding: 'UTF-8')
} catch (hudson.AbortException e) {
  spectralOutput = spectralOutput.replace('\n', '<br>')
  // Parse Spectral output
  if (!spectralOutput.contains('0 errors')) {
    echo spectralOutput
    currentBuild.result = 'FAILED'
  }
  echo spectralOutput
}

This gives me an error

java.lang.NullPointerException: Cannot invoke method replace() on null object

So if the bat script has an error exit code, it probably raises an exception and nothing is stored in spectralOutput... Is there a way to always store the output in spectralOutput, regardless of the exit code?

Should I pipe the script to a text file and then read in that text file?

Seems like returnStatus and returnStdout can't be used together.


Solution

  • It's a known Jenkins idiosyncrasy. You will have to modify your script in one of the two possible ways:

    1. Make a failproof script. Easier than it sounds for bat - add exit 0 at the end. This way the script always succeeds and you get your STDOUT.
    2. If for some reason you need the exit code you will have to complicate things a little. Redirect output to a temporary file and replace returnStdout with returnStatus. The step will always succeed and it's up to you to check the exit code and react to it. And you will have to add a readFile step to get the script output.

    If you want the step to be displayed as failed (and you should) you will have to use the second approach, but remove returnStatus and let it fail. Then surround it with either try/catch or catchError step.