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

Default values in closures are not work

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • workflow-cps-plugin
    • None

      if (jobConfig.scm?.type in ['github', null]) {
        this.handleScmResponse = {
          // TODO: check why default values doesn't work
          script, state = '0', message = null ->
          logGithubTestStatus script, state, message
        }
      } else {
        this.handleScmResponse = {
          jobConfig, script, nameOfTest, state = null, message = null ->
          def currentMessage = message ?: stateMap[state]
          echo "State: ${state}, Message: ${currentMessage}"
        }
      }
      
      def logGithubTestStatus(script, String state = '0', message = '') {
        script.echo " ${message}"
        if (state == '-1') script.error "test failed"
      }
      
      def handleScmFromShell(script, String command) {
        def result = script.sh(script: command, returnStatus: true)
        this.handleScmResponse(script, result ? '-1' : '+1')
      }

      Here we use default values for parameters in this.handleScmResponse closure. But if we call method handleScmFromShell which will call this.handleScmResponse closure which will call logGithubTestStatus method then we will get null values for state and message parameters in logGithubTestStatus.

      Provided script will be loaded to main pipeline script using method load(). It appears defaults in pipelines that are loaded with the load() function with default parameters in closures never have the defaults resolved (so the default state = '0', for example, would actually be null).

      Simple pipeline script to test an issue:

      node 'master', {
         try {
            sh 'echo "def f = { x = [1] -> x += 1; x += 2; println x }\nf()\nf()\nprintln x\nreturn this" > test.groovy'
            load 'test.groovy'
         } finally {
            sh 'rm test.groovy'
         }
      }
      

      The example output from a testing job:

      [workspace] Running shell script
      + echo 'def f = { x = [1] -> x += 1; x += 2; println x }
      f()
      f()
      println x
      return this'
      [Pipeline] load
      [Pipeline] { (test.groovy)
      [Pipeline] }
      [Pipeline] // load
      [Pipeline] sh
      [workspace] Running shell script
      + rm test.groovy
      [Pipeline] }
      [Pipeline] // node
      [Pipeline] End of Pipeline
      java.lang.NullPointerException: Cannot execute null+1
      

            Unassigned Unassigned
            very_important_username Some Guy
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: