61

I'm trying to use the following code to execute builds, and in the end, execute post build actions when builds were successful. Still, I get a MultipleCompilationErrorsException, saying that my try block is Not a valid section definition. Please help, I tried a lot reorganize the block but can't seem to be able to solve the issue.

pipeline{

agent any 
    try {
        stages{
            stage("Parallel 1") {
                steps {
                    parallel (
                       'firstTask' : { 
                            build( "DSL-Controll-Demo-Fibonacci-1" )
                        },
                        'secondTask' : { 
                            build( "DSL-Controll-Demo-Fibonacci-2" )
                        }
                    )
                }
            }
            stage("Feature") {
                steps {
                        build( "DSL-Controll-Demo-Fibonacci-5" )
                        build( "DSL-Controll-Demo-Fibonacci-6" )
                }
            }
            stage("Parallel 2") {
                steps{
                    parallel (
                        "thirdTask" : { 
                            build( "DSL-Controll-Demo-Fibonacci-3" )
                        },
                        "forthTask" : { 
                            build( "DSL-Controll-Demo-Fibonacci-4" )
                        }
                    )
                }
            }
        }
    }   

    catch(all) {
        currentBuild.result = 'FAILURE'
    }   

    if(currentBuild.result != 'FAILURE') {
        stages{
            stage("Post Build") {
                steps {
                    build("DSL-Controll-Demo-Fibonacci-7")
                }   
            }   
        }
    }
}
Mike
  • 14,010
  • 29
  • 101
  • 161
lenkovi
  • 1,708
  • 2
  • 11
  • 16

5 Answers5

115

try like this (no pun intended btw)

script {
  try {
      sh 'do your stuff'
  } catch (Exception e) {
      echo 'Exception occurred: ' + e.toString()
      sh 'Handle the exception!'
  }
}

The key is to put try...catch in a script block in declarative pipeline syntax. Then it will work. This might be useful if you want to say continue pipeline execution despite failure (eg: test failed, still you need reports..)

Lahiru Chandima
  • 22,324
  • 22
  • 103
  • 179
Ciado
  • 1,996
  • 2
  • 17
  • 15
  • 9
    Note that the generic `Exception` is the only exception allowed (by default) by the Jenkins security sandbox. – cowlinator Apr 13 '20 at 22:48
42

You're using the declarative style of specifying your pipeline, so you must not use try/catch blocks (which are for Scripted Pipelines), but the post section. See: https://jenkins.io/doc/book/pipeline/syntax/#post-conditions

User5910
  • 463
  • 5
  • 13
Mike
  • 476
  • 6
  • 5
  • Using the declarative script{} step, is there a way to to translate an exception to a human readable form? Eg: when a build variable doesn't match a regex how can you deliberately break the build with an error message? IndexOutOfBoundsException doesn't really tell anything about the problem at hand.. – sanya Sep 05 '18 at 20:05
  • There is only 1 post section in a declarative pipeline, so if you use parallel blocks, you cannot cleanup and archive logs in each parallel (which could run on a separate node) without a try/catch. –  Jun 14 '19 at 13:37
  • 1
    This answer is not correct based on: https://stackoverflow.com/questions/43293501/jenkins-pipeline-try-catch-for-particular-stage-and-subsequent-conditional-ste am I missing something? – James Nelson Dec 05 '19 at 04:30
19

Look up the AbortException class for Jenkins. You should be able to use the methods to get back simple messages or stack traces. In a simple case, when making a call in a script block (as others have indicated), you can call getMessage() to get the string to echo to the user. Example:

script {
        try {
            sh "sudo docker rmi frontend-test"
        } catch (err) {
            echo err.getMessage()
            echo "Error detected, but we will continue."
        }
        ...continue with other code...
}
Robert Casey
  • 1,511
  • 18
  • 19
13

This answer worked for me:

pipeline {
  agent any
  stages {
    stage("Run unit tests"){
      steps {
        script {
          try {
            sh  '''
              # Run unit tests without capturing stdout or logs, generates cobetura reports
              cd ./python
              nosetests3 --with-xcoverage --nocapture --with-xunit --nologcapture --cover-package=application
              cd ..
              '''
          } finally {
            junit 'nosetests.xml'
          }
        }
      }
    }
    stage ('Speak') {
      steps{
        echo "Hello, CONDITIONAL"
      }
    }
  }
}
James Nelson
  • 833
  • 10
  • 15
6

try/catch is scripted syntax. So any time you are using declarative syntax to use something from scripted in general you can do so by enclosing the scripted syntax in the scripts block in a declarative pipeline. So your try/catch should go inside stage >steps >script.

This holds true for any other scripted pipeline syntax you would like to use in a declarative pipeline as well.

KBM
  • 341
  • 4
  • 16