Default values in closures are not work

This issue is archived. You can view it, but you can't modify it. Learn more

XMLWordPrintable

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Minor
    • Component/s: workflow-cps-plugin
    • Environment:

      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
      

            Assignee:
            Unassigned
            Reporter:
            Some Guy
            Archiver:
            Jenkins Service Account

              Created:
              Updated:
              Archived: