How to add error handling code to `catchError()` in Jenkins? - jenkins

If I have a pipeline where individual stages are allowed to fail, without failing the whole job, how can I add error handling to, for instance, send an email to an admin, when that stage fails? I've tried using post failure, but it doesn't work.
pipeline {
agent any
stages {
stage('1') {
steps {
sh 'exit 0'
}
}
stage('2') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "exit 1"
}
}
post {
failure {
echo 'Sending email to admin...'
}
}
}
stage('3') {
steps {
sh 'exit 0'
}
}
}
}
I got this question in a comment and thought it was worth asking and answering as a proper question.

Unfortunately, for now, I think the only way is to use try catch in a script block and re-throw the error after performing the error handling. See example below:
pipeline {
agent any
stages {
stage('1') {
steps {
sh 'exit 0'
}
}
stage('2') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
script {
try {
sh "exit 1"
} catch (e) {
echo 'send email'
throw e
}
}
}
}
}
stage('3') {
steps {
sh 'exit 0'
}
}
}
}

Related

Execute code block if stage fails, but proceed with other stages

We would like to send an email if a stage fails. The stage should be marked as unstable, but overall build result should not be affected by the result of this stage. This is the code snippet that we are using:
stage("Stage 1")
{
catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE')
{
sh 'scriptThatCanExitWithStatus1.sh'
}
}
It works fine, but we are not able to define the code that should be executed if shell script fails. How can we execute custom error handling block of code if scriptThatCanExitWithStatus1.sh fails (ex. send an email to sys admin)?
This is how I solved the problem:
stage("Stage 1")
{
success = false
catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE')
{
sh 'scriptThatCanExitWithStatus1.sh'
success = true
}
if (!success) {
// send mail
}
}
Another way is to use try catch in a script block and re-throw the error after performing the error handling. See example below:
pipeline {
agent any
stages {
stage('1') {
steps {
sh 'exit 0'
}
}
stage('2') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
script {
try {
sh "exit 1"
} catch (e) {
echo 'send email'
throw e
}
}
}
}
}
stage('3') {
steps {
sh 'exit 0'
}
}
}
}

How to use parallelsAlwaysFailFast() in scripted pipeline?

How to use parallelsAlwaysFailFast() in Jenkins Scripted Pipeline?
I could not find any example for this.
Edited, here is the code I use and the 'Blue Ocean' screenshot:
stage("Build") {
parallel([
failFast: true,
"Stage 1":{
stage("Stage 1") {
stage("a1") {
println("a1")
};
stage("a2") {
println("a2")
}
}
},
"Stage 2":{
stage("Stage 2") {
stage("b1") {
sh '''pwd'''
};
stage("b2") {
echo '''Here we can see the InterruptedException'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
error "Failing the stage"
}
}
}
}
])
}
Blue Ocean img
How can I make all the stages that are executed in parallel to fail as well?
Thanks.
As far as I know, there is no way to change that behavior for all the future parallel stages.
However one can change it for any given set of parallel stages, like this:
def parallel_stages = [:].asSynchronized()
parallel_stages['one'] = {
stage ('One') {
script {
println "One"
}
}
}
parallel_stages['two'] = {
stage ('Two') {
script {
println "Two"
}
}
}
// Here you set this for the given parallel stage
parallel_stages.failFast = true
parallel parallel_stages

How to continue Jenking stage on failure

I would like to run pipeline with 2 stages. If any of the stage is failed, next stage should be started (not skipped). Currently if 1st stage is failed, next stage will be skipped.
Thank you for any help.
pipeline {
options { buildDiscarder(logRotator(numToKeepStr: '5', artifactNumToKeepStr: '5')) }
agent { label 'docker_gradle' }
triggers {
cron(env.BRANCH_NAME == 'develop' || env.BRANCH_NAME == 'master' ? '#daily' : '')
}
stages {
stage('Init') {
steps {
sh 'chmod +x gradlew'
}
}
stage('task1') {
when { anyOf { branch 'feature/*'; branch 'develop' }}
steps {
container(name: 'gradle') {
sh 'gradle clean task1'
}
}
}
stage('task2') {
when { anyOf { branch 'feature/*'; branch 'develop' }}
steps {
container(name: 'gradle') {
sh 'gradle clean task2'
}
}
}
}
post {
always {
script {
currentBuild.result = currentBuild.result ?: 'SUCCESS'
cucumber buildStatus: 'UNSTABLE',
failedFeaturesNumber: 1,
failedScenariosNumber: 1,
skippedStepsNumber: 1,
failedStepsNumber: 1,
reportTitle: 'Reoport',
fileIncludePattern: '**/cucumber.json',
sortingMethod: 'ALPHABETICAL',
trendsLimit: 100
}
}
}
}
1.You can change sh 'gradle clean task1' to
sh 'gradle clean task1 || true'
This will make sh return success even if sh scrip fails
2.You can also use try catch
Check this link: https://www.jenkins.io/doc/book/pipeline/syntax/#flow-control
for example:
stage("task1"){
steps {
script {
try {
sh 'gradle clean task1'
} catch (err) {
echo err.getMessage()
}
}
}
}

Display Jenkins pipeline stage as failed without failing the whole job

Could you please tell me what I am doing wrong. I would like to failure a Stage1. Stage2 should be green and that case, and I would like to have whole build Success. What I am doing wrong?
pipeline{
agent none
stages{
stage ("Stage1") {
steps {
script{
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
stage ("stege1") {
def seekAndDestroy = build job: 'SeekAndDestroy' // it is going FAILURE
}
}
stage ("Stege2") {
sh "exit 0"
}
}
}
}
}
}
catchError is something similar to try/catch block, so you need to catch error of the code you are executing. For details - see documentation: https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#catcherror-catch-error-and-set-build-result-to-failure
This works:
pipeline{
agent { label 'jdk11' }
stages {
stage ("stage 1") {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "exit 1"
}
}
}
stage ("stage 2") {
steps {
sh "exit 0"
}
}
}
}
And the result is:

Jenkins multipe post sections per stage

I have two question for usage of post section in Jenkins pipeline
1.Can we use multiple post section per stage in Jenkins declarative Pipeline?
2.Can we run sh command in post section?
pipeline{
stages{
stage("....") {
steps {
script {
....
}
}
post {
failure{
sh "....."
}
}
stage("Second stage") {
when {
expression { /*condition */ }
}
steps {
script{
....
}
post {
always {
script {
sh "..."
}
}
}
}
}
You can find information in https://jenkins.io/doc/book/pipeline/syntax/#post
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post {
success {
sh label: 'success', script: 'ls'
}
failure {
sh label: 'failure', script: 'ls'
}
aborted {
sh label: 'aborted', script: 'ls'
}
}
}
You can use Post steps each Stage, but pipeline will stop on first failure. In example below, if Stage 1 fail Stage 2 will be skipped. Post after all stages will always executed.
pipeline{
stages{
stage("Stage 1") {
steps {
catchError(message: 'catch failure') {
script {
sh "echo stage 1"
}
}
}
post {
always {
sh "echo post stage 1"
}
}
}
stage("Stage 2") {
when {
expression { /*condition */ }
}
steps {
script{
sh "echo stage 2"
}
}
post {
always {
script {
sh "echo post stage 2"
}
}
}
}
}
post {
always {
sh "echo post after all stages"
}
}
}

Resources