Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-59529

Build is not failing when powershell script exits with "MissingMandatoryParameter" or "CommandNotFoundException"

    • 1.36

       A build will not fail when a powershell script encounters an error "MissingMandatoryParameter" or "CommandNotFoundException".

      I would expect an error code other than 0, or, for the script to fail.

      Here are some examples:

      powershell "gobbledygook"
      

      Results in something similar to:

      [Pipeline] echo
      
          Running powershell command:
          gobbledygook
        
      [Pipeline] powershell
      powershell.exe : gobbledygook : The term 'gobbledygook' is not recognized as the name of a cmdlet, function, script file, or operable 
      At C:\jenkins_workspace\Jenkins Playground\WebAppTest - Deploy from Git branch@tmp\durable-25a0caf8\powershellWrapper.ps1:3 char:1
      + & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Comm ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : NotSpecified: (gobbledygook : ...e, or operable :String) [], RemoteException
          + FullyQualifiedErrorId : NativeCommandError
       
      program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
      At C:\jenkins_workspace\Jenkins Playground\WebAppTest - Deploy from Git 
      branch@tmp\durable-25a0caf8\powershellScript.ps1:3 char:5
      +     gobbledygook
      +     ~~~~~~~~~~~~
      
          + CategoryInfo          : ObjectNotFound: (gobbledygook:String) [], CommandNotFoundException
          + FullyQualifiedErrorId : CommandNotFoundException
      
       
      
      [Pipeline] echo
      Powershell exit status: 0

      and

      powershell "buildVS 'Release' -nuget $true"
      

      Results in something similar to:

      [Pipeline] echo
      
          Running powershell command:
          buildVS  'Release' -nuget $true
        
      [Pipeline] powershell
      powershell.exe : buildVS : Cannot process command because of one or more missing mandatory parameters: config.
      At C:\jenkins_workspace\Jenkins Playground\WebAppTest - Deploy from Git branch@tmp\durable-9137f721\powershellWrapper.ps1:3 char:1
      + & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Comm ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : NotSpecified: (buildVS : Canno...meters: config.:String) [], RemoteException
          + FullyQualifiedErrorId : NativeCommandError
       
      At C:\jenkins_workspace\Jenkins Playground\WebAppTest - Deploy from Git 
      branch@tmp\durable-9137f721\powershellScript.ps1:3 char:5
      
      +     buildVS  'Release' -nuget $true
      
      +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      
          + CategoryInfo          : InvalidArgument: (:) [buildVS], ParameterBindingException
      
          + FullyQualifiedErrorId : MissingMandatoryParameter,buildVS
      
       
      
      [Pipeline] echo
      Powershell exit status: 0

       

          [JENKINS-59529] Build is not failing when powershell script exits with "MissingMandatoryParameter" or "CommandNotFoundException"

          Brent Zeiss added a comment - - edited

          According to this answer on SO, the script should be exiting with an exit code of 1 when  the -NonInteractive flag is used.  At least in the case of MissingMandatoryParameter.

          Brent Zeiss added a comment - - edited According to  this answer on SO , the script should be exiting with an exit code of 1 when  the -NonInteractive flag is used.  At least in the case of  MissingMandatoryParameter .

          Brent Zeiss added a comment -

          Alright, just discovered some odd behavior.

          If the Stdout is returned, then the script will fail as expected...

          I would expect both to return a postive exit code!

          The downside of using returnStdout is that none of that output will be displayed in the logs.

          pipeline {
              agent any
              stages {
                  stage('gobbledygook - will pass') {
                      steps{
                          powershell script: 'gobbledygook'
                      }
                  }
                  stage('gobbledygook - will fail') {
                      steps{
                          powershell returnStdout: true, script: 'gobbledygook'
                      }
                  }
              }
          }
          

          And this is the output:

          [Pipeline] Start of Pipeline
          [Pipeline] node
          Running on Jenkins in C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample
          [Pipeline] {
          [Pipeline] stage
          [Pipeline] { (gobbledygook - will pass)
          [Pipeline] powershell
          powershell.exe : gobbledygook : The term 'gobbledygook' is not recognized as the name of a cmdlet, function, script file, or operable 
          At C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample@tmp\durable-805172ca\powershellWrapper.ps1:3 char:1
          + & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Comm ...
          + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              + CategoryInfo          : NotSpecified: (gobbledygook : ...e, or operable :String) [], RemoteException
              + FullyQualifiedErrorId : NativeCommandError
           
          program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
          At C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample@tmp\durable-805172ca\powershellScript.ps1:1 char:1
          
          + gobbledygook
          
          + ~~~~~~~~~~~~
          
              + CategoryInfo          : ObjectNotFound: (gobbledygook:String) [], CommandNotFoundException
          
              + FullyQualifiedErrorId : CommandNotFoundException
          
           
          
          [Pipeline] }
          [Pipeline] // stage
          [Pipeline] stage
          [Pipeline] { (gobbledygook - will fail)
          [Pipeline] powershell
          gobbledygook : The term 'gobbledygook' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify 
          that the path is correct and try again.
          At C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample@tmp\durable-bf7e742d\powershellScript.ps1:1 char:1
          + gobbledygook
          + ~~~~~~~~~~~~
              + CategoryInfo          : ObjectNotFound: (gobbledygook:String) [], CommandNotFoundException
              + FullyQualifiedErrorId : CommandNotFoundException
           
          
          [Pipeline] }
          [Pipeline] // stage
          [Pipeline] }
          [Pipeline] // node
          [Pipeline] End of Pipeline
          ERROR: script returned exit code 1
          Finished: FAILURE
          

          Brent Zeiss added a comment - Alright, just discovered some odd behavior. If the Stdout is returned, then the script will fail as expected... I would expect both to return a postive exit code! The downside of using returnStdout is that none of that output will be displayed in the logs. pipeline { agent any stages { stage( 'gobbledygook - will pass' ) { steps{ powershell script: 'gobbledygook' } } stage( 'gobbledygook - will fail' ) { steps{ powershell returnStdout: true , script: 'gobbledygook' } } } } And this is the output: [Pipeline] Start of Pipeline [Pipeline] node Running on Jenkins in C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample [Pipeline] { [Pipeline] stage [Pipeline] { (gobbledygook - will pass) [Pipeline] powershell powershell.exe : gobbledygook : The term 'gobbledygook' is not recognized as the name of a cmdlet, function, script file, or operable At C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample@tmp\durable-805172ca\powershellWrapper.ps1:3 char :1 + & powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Comm ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (gobbledygook : ...e, or operable : String ) [], RemoteException + FullyQualifiedErrorId : NativeCommandError program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample@tmp\durable-805172ca\powershellScript.ps1:1 char :1 + gobbledygook + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (gobbledygook: String ) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (gobbledygook - will fail) [Pipeline] powershell gobbledygook : The term 'gobbledygook' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At C:\jenkins_workspace\Jenkins Playground\PowershellErrorExample@tmp\durable-bf7e742d\powershellScript.ps1:1 char :1 + gobbledygook + ~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (gobbledygook: String ) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline ERROR: script returned exit code 1 Finished: FAILURE

          Keith Hill added a comment -

          Not only does the PowerShell step not fail with a missing parameter:

          pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ". 'C:\KD\KLM\powershellHelper.ps1'; Execute-AndWriteOutput -MainScript 'C:\KD\KLM\powershellWrapper.ps1' -LogFile 'C:\KD\KLM\jenkins-log.txt' -ResultFile 'C:\KD\KLM\jenkins-result.txt';"
          
          WARNING: LASTEXITCODE is 0
          WARNING: Exiting with 0
          
          03-27 16:21:59 78> gc .\jenkins-log.txt
          build.ps1: C:\KD\KLM\powershellScript.ps1:1
          Line |
             1 | ./build.ps1 -Clean-BuildType XYZZY -CreatePackage -JenkinsBuild -Verb … 
               |~~~~~~~~~~~~~~~~|
               |A parameter cannot be found that matches parameter name 'Clean-BuildType'.|
          

          It does not fail even the script is not found:

          pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ". 'C:\KD\KLM\powershellHelper.ps
          1'; Execute-AndWriteOutput -MainScript 'C:\KD\KLM\powershellWrapper.ps1' -LogFile 'C:\KD\KLM\jenkins-log.txt' -ResultFile 'C:\KD\KLM\jenkins-result.txt';"
          
          WARNING: LASTEXITCODE is 0
          WARNING: Exiting with 0
          
          03-27 16:19:25 69> gc .\jenkins-log.txt
          ./build.ps1: C:\KD\KLM\powershellScript.ps1:1
          Line |
             1 |  ./build.ps1 -Clean -BuildType XYZZY -CreatePackage -JenkinsBuild -Ver …
               |  ~~~~~~~~~~~
               | The term './build.ps1' is not recognized as a name of a cmdlet, function, script file, or
               | executable program. Check the spelling of the name, or if a path was included, verify that the path
               | is correct and try again.
          

          Nor does it fail when parameter validation fails:

          pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ". 'C:\KD\KLM\powershellHelper.ps
          1'; Execute-AndWriteOutput -MainScript 'C:\KD\KLM\powershellWrapper.ps1' -LogFile 'C:\KD\KLM\jenkins-log.txt' -ResultFile 'C:\KD\KLM\jenkins-result.txt';"
          
          WARNING: LASTEXITCODE is 0
          WARNING: Exiting with 0
          
          03-27 16:21:11 75> gc .\jenkins-log.txt
          build.ps1: C:\KD\KLM\powershellScript.ps1:1
          Line |
             1 |  ./build.ps1 -Clean -BuildType XYZZY -CreatePackage -JenkinsBuild-Verb …
               |                                ~~~~~
               | Cannot validate argument on parameter 'BuildType'. The argument "XYZZY" does not belong to the set
               | "Debug,Release" specified by the ValidateSet attribute. Supply an argument that is in the set and
               | then try the command again.
          

          The good news is that there's an easy fix and if someone could point me to the repo where the PowerShell plugin exists, I'd be happy to submit a PR. Basically the generated powershellScript.ps1 file needs to change from generating this:

          <specified command>
          exit $LASTEXITCODE;
          

          to this:

          try {
              <specified command>
          } catch { 
              throw 
          }
          
          exit $LASTEXITCODE
          

          PowerShell script errors do not normally update $LASTEXITCODE - that is updated when an external binary exits. By putting the users "command" within a try/catch that changes the error handling behavior so that this script throws. That exception is picked up by the calling powershellWrapper.ps1 script as a PowerShell script error.

          Keith Hill added a comment - Not only does the PowerShell step not fail with a missing parameter: pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ". 'C:\KD\KLM\powershellHelper.ps1'; Execute-AndWriteOutput -MainScript 'C:\KD\KLM\powershellWrapper.ps1' -LogFile 'C:\KD\KLM\jenkins-log.txt' -ResultFile 'C:\KD\KLM\jenkins-result.txt';" WARNING: LASTEXITCODE is 0 WARNING: Exiting with 0 03-27 16:21:59 78> gc .\jenkins-log.txt build.ps1: C:\KD\KLM\powershellScript.ps1:1 Line | 1 | ./build.ps1 -Clean-BuildType XYZZY -CreatePackage -JenkinsBuild -Verb … |~~~~~~~~~~~~~~~~| |A parameter cannot be found that matches parameter name 'Clean-BuildType'.| It does not fail even the script is not found: pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ". 'C:\KD\KLM\powershellHelper.ps 1'; Execute-AndWriteOutput -MainScript 'C:\KD\KLM\powershellWrapper.ps1' -LogFile 'C:\KD\KLM\jenkins-log.txt' -ResultFile 'C:\KD\KLM\jenkins-result.txt';" WARNING: LASTEXITCODE is 0 WARNING: Exiting with 0 03-27 16:19:25 69> gc .\jenkins-log.txt ./build.ps1: C:\KD\KLM\powershellScript.ps1:1 Line | 1 | ./build.ps1 -Clean -BuildType XYZZY -CreatePackage -JenkinsBuild -Ver … | ~~~~~~~~~~~ | The term './build.ps1' is not recognized as a name of a cmdlet, function, script file, or | executable program. Check the spelling of the name, or if a path was included, verify that the path | is correct and try again. Nor does it fail when parameter validation fails: pwsh -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ". 'C:\KD\KLM\powershellHelper.ps 1'; Execute-AndWriteOutput -MainScript 'C:\KD\KLM\powershellWrapper.ps1' -LogFile 'C:\KD\KLM\jenkins-log.txt' -ResultFile 'C:\KD\KLM\jenkins-result.txt';" WARNING: LASTEXITCODE is 0 WARNING: Exiting with 0 03-27 16:21:11 75> gc .\jenkins-log.txt build.ps1: C:\KD\KLM\powershellScript.ps1:1 Line | 1 | ./build.ps1 -Clean -BuildType XYZZY -CreatePackage -JenkinsBuild-Verb … | ~~~~~ | Cannot validate argument on parameter 'BuildType'. The argument "XYZZY" does not belong to the set | "Debug,Release" specified by the ValidateSet attribute. Supply an argument that is in the set and | then try the command again. The good news is that there's an easy fix and if someone could point me to the repo where the PowerShell plugin exists, I'd be happy to submit a PR. Basically the generated powershellScript.ps1 file needs to change from generating this: <specified command> exit $LASTEXITCODE; to this: try { <specified command> } catch { throw } exit $LASTEXITCODE PowerShell script errors do not normally update $LASTEXITCODE - that is updated when an external binary exits. By putting the users "command" within a try/catch that changes the error handling behavior so that this script throws. That exception is picked up by the calling powershellWrapper.ps1 script as a PowerShell script error.

          Carroll Chiou added a comment -

          Carroll Chiou added a comment - PR here: https://github.com/jenkinsci/durable-task-plugin/pull/131

            Unassigned Unassigned
            brent_zeiss Brent Zeiss
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: