Expected a step # line 37, column 17. try{ - jenkins

i am trying to use try catch inside stage but getting error as mentioned in subject.
Here i am using build job to call another jenkins pipeline which works without try-catch.
Not sure if we can use try-catch outside shell with build job ?. \n
\n Requirement is to use try catch with build job so that in case of any failure , it will skip this step, echo message and go to next step.
{
stage('Pull Pipeline') {
try {
build job: "../new pipeline/test_dummy", wait: true
}
catch (Exception e) {
echo "release having error"
}
}
}

Related

Jenkins reporting build success when a stage fails

Got some undesirable behaviour when it comes to running a build via Jenkins, am getting an error in the logs (which subsequently causes the unit tests not to run and should be a build failure), but the build is reporting as a pass
node('el7') {
// Clean workspace directory
stage ('Checkout Codebase') {
deleteDir()
checkout scm
}
// Run Unit Tests Stage
stage ('Run Unit Tests') {
try {
sh '''#!/usr/bin/env bash
npm install
make build
make run-tests
'''
UNIT_TESTS = 'success'
} catch (Exception error) {
UNIT_TESTS = 'failure'
}
// Notify GitHub of result
notifyGithub(UNIT_TESTS, 'Unit Tests', 'Jenkins Unit Tests')
// Set Build Status
if (UNIT_TESTS == 'success') {
currentBuild.result = 'SUCCESS'
} else {
currentBuild.result = 'FAILURE'
}
} // end run unit test stage
}
}
The error I see is
[08:17:52] Starting 'test'...
[33m20 06 2022 08:17:52.649:WARN [karma-server]: [39mPassing raw CLI options to `new Server(config, done)` is deprecated. Use `parseConfig(configFilePath, cliOptions, {promiseConfig: true, throwErrors: true})` to prepare a processed `Config` instance and pass that as the `config` argument instead.
failed to add custom browserify preprocessor
TypeError: Cannot read property '$inject' of undefined
Is there a way to catch this (thought I was to be honest by wrapping it in a try/catch) or am i not reporting the status correctly?
I am on Jenkins 2.319.2

How to kill a stage of Jenkins Pipeline?

I've a Jenkins pipeline with multiple stages but because of some issue, in one of the stages, it is likely to run longer unnecessarily.
Instead of aborting entire pipeline build and skip next stages, I want to kill that specific stage on which other stages are not dependent.
Is there a way to kill specific stage of Jenkins pipeline?
There are ways to skip a stage. But I'm not sure if there are options to kill a long running stage. I'd simply add a conditional expression to run the stage or not OR maybe you could put a timeout condition wrapped in a try..catch block for the long running unnecessary stage to skip and proceed to other stages you want like as below.
pipeline {
agent any
stages {
stage('stage1') {
steps {
script {
try {
timeout(time: 2, unit: 'NANOSECONDS')
echo "do your stuff"
} catch (Exception e) {
echo "Ended the never ending stage and proceeding to the next stage"
}
}
}
}
stage('stage2') {
steps {
script {
echo "Hi Stage2"
}
}
}
}
}
OR Check this page for conditional step/stage.
You can try using "try/catch" block in the scripted pipeline. Even if there is error in a particular stage, Jenkins will continue to execute the next stage.
node {
stage('Example') {
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed, I should sound the klaxons!'
throw
}
}
}
You can refer documentation here: https://jenkins.io/doc/book/pipeline/syntax/

setting status of a build in jenkins

I have a jenkins job.
It is pretty simple: pull from git, and run the build.
The build is just one step:
Execute window command batch
In my use case, I will need to run some python scripts.
Some will fail, some others will not.
python a.py
python b.py
What does determine the final status of the build?
It seems I can edit that by:
echo #STABLE > build.proprieties
but how are the STABLE/UNSTABLE status assigned if not specified by the user?
What happens if b.py raise an error and fails?
Jenkins interprets a pipeline as failed if a command returns an exit code unequal zero.
Internally the build status is set with currentBuild.currentResult which can have three values: SUCCESS, UNSTABLE, or FAILURE.
If you want to control the failure / success of your pipeline yourself you can catch exceptions / exit codes and manually set the value for currentBuild.currentResult. Plugins also use this attribute to change the result of the pipeline.
For example:
stage {
steps {
script {
try {
sh "exit 1" // will fail the pipeline
sh "exit 0" // would be marked as passed
currentBuild.currentResult = 'SUCCESS'
} catch (Exception e) {
currentBuild.currentResult = 'FAILURE'
// or currentBuild.currentResult = 'UNSTABLE'
}
}
}}

Jenkins pipeline - try catch for particular stage and subsequent conditional step

I'm trying to replicate the equivalent of a conditional stage in Jenkins pipeline using a try / catch around a preceding stage, which then sets a success variable, which is used to trigger the conditional stage.
It appears that a try catch block is the way to go, setting a success var to SUCCESS or FAILED, which is used as part of a when statement later (as part of the conditional stage).
The code I am using is as follows:
pipeline {
agent any
stages {
try{
stage("Run unit tests"){
steps{
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 ..
'''
currentBuild.result = 'SUCCESS'
}
}
} catch(Exception e) {
// Do something with the exception
currentBuild.result = 'SUCCESS'
}
stage ('Speak') {
when {
expression { currentBuild.result == 'SUCCESS' }
}
steps{
echo "Hello, CONDITIONAL"
}
}
}
}
The latest syntax error I am receiving is as follows:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup
failed:
WorkflowScript: 4: Expected a stage # line 4, column 9.
try{
I've also tried lots of variations.
Am I taking the wrong approach here? This seems like a fairly common requirement.
Thanks.
This might solve your problem depending on what you are going for. Stages are only run when the preceding stages succeed, so if you actually have two stages like in your example, and if you want the second to only run when the first succeeds, you want to ensure that the first stage fails appropriately when tests fail. Catching will prevent the (desirable) failure. Finally will preserve the failure, and can also still be used to grab your test results.
So here, the second stage will only run when the tests pass, and the test results will be recorded regardless:
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"
}
}
}
}
Note that I'm actually using try in a declarative pipeline, but like StephenKing says, you can't just use try directly (you have to wrap arbitrary groovy code in the script step).

Jenkins Pipeline: Try/catch inside a retry block

I have problems with my Jenkins pipeline. I want to do the following:
if the Build Environment already exists in the Workspace then execute a (incremental) build using the previous Environment.
If that fails retry again with a clean build (delete previous Build Environment, then build again)
I am trying to do this by:
retry(1) {
try {
prepareEnvironment()
setupBuildEnvironment() // sets up environment if it is not present yet
runBuild()
} catch (e) {
echo 'Err: Incremental Build failed with Error: ' + e.toString()
echo ' Trying to build with a clean Workspace'
removeOldBuildEnvironment()
} finally {
cleanupEnvironment()
}
}
When I run this in Jenkins and the runBuild() step fails I get:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:
Scripts not permitted to use new java.lang.Exception java.lang.String
I think the problem is the try/catch inside the retry(1) block. Any suggestions how to fix that
I also tried it without the retry. Here I had the problem that if the
bat "..."
step inside runBuild() returns a exception the pipeline Stage is marked as fail even if I catch the exception and the clean build is a success.
Any suggestions?
The error message is not because the try/catch but because of throwing exception in the prepareEnvironment, setupBuildEnvironment or runBuild methods, like throw new Exception("message") which is not allowed in sandbox mode. What is allowed is using the error step like so:
def runBuild() {
// ...
error "ERR"
}
This step will throw a hudson.AbortException with the message specified.
The catch block in you code will catch this exception and print the proper message then invoke removeOldBuildEnvironment
On the other hand with this modification done your script will still not work as expected as the exception is swallowed by the catch block, so the retry step will not execute the code again. To make it work the exception needs to be thrown again from the catch block (note that you have to use retry(2) instead of retry(1))
retry(2) {
try {
prepareEnvironment()
setupBuildEnvironment() // sets up environment if it is not present yet
runBuild()
} catch (e) {
echo 'Err: Incremental Build failed with Error: ' + e.toString()
echo ' Trying to build with a clean Workspace'
removeOldBuildEnvironment()
throw e
} finally {
cleanupEnvironment()
}
}
Go to script approval (in Manage Jenkins, somewhere at the bottom) and approve toString method for Exception.
If you can't find script approval, then install plugin https://wiki.jenkins-ci.org/display/JENKINS/Script+Security+Plugin first.
You might need to visit that page when you see RejectedAccessException.
Try to uncheck the checkbox "Use Groovy Sandbox".

Resources