A continuación, he mostrado diferentes formas de manejo de errores para el enfoque declarativo:
failfast
en tubería paralela
https://issues.jenkins-ci.org/browse/JENKINS-55459?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel
Si un usuario tiene un script de canalización declarativa con etapas paralelas y se configuran failFast true
para esas etapas, si una de las etapas falla, la compilación se cancela inmediatamente.
NOTA: sh 'false'
-> Puede fallar la etapa
pipeline {
agent any
stages {
stage('Validate Fail fast') {
failFast true
parallel {
stage('stage A') {
steps {
echo 'stage A started'
sleep 5
sh 'false'
echo 'stage A Ended'
}
}
stage('stage B') {
steps {
echo 'stage B started'
sleep 10
echo 'stage B Ended'
}
}
stage('stage C') {
steps {
echo 'stage C started'
echo 'stage C Ended'
}
}
}
}
stage('final stage sequential') {
steps {
script {
echo "The complete run!"
}
}
}
}
}
Cuando failFast true
termina las tareas paralelas.
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/ErrorHandling
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Validate Fail fast)
[Pipeline] parallel
[Pipeline] { (Branch: stage A)
[Pipeline] { (Branch: stage B)
[Pipeline] { (Branch: stage C)
[Pipeline] stage
[Pipeline] { (stage A)
[Pipeline] stage
[Pipeline] { (stage B)
[Pipeline] stage
[Pipeline] { (stage C)
[Pipeline] echo
stage A started
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
stage B started
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] echo
stage C started
[Pipeline] echo
stage C Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] sh
+ false
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage A
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage B
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] stage
[Pipeline] { (final stage sequential)
Stage "final stage sequential" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE
Cuando "failFast falso" aún continúa ejecuta otras tareas paralelas.
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/ErrorHandling
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Validate Fail fast)
[Pipeline] parallel
[Pipeline] { (Branch: stage A)
[Pipeline] { (Branch: stage B)
[Pipeline] { (Branch: stage C)
[Pipeline] stage
[Pipeline] { (stage A)
[Pipeline] stage
[Pipeline] { (stage B)
[Pipeline] stage
[Pipeline] { (stage C) (hide)
[Pipeline] echo
stage A started
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
stage B started
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] echo
stage C started
[Pipeline] echo
stage C Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] sh
+ false
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage A
[Pipeline] echo
stage B Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] stage
[Pipeline] { (final stage sequential)
Stage "final stage sequential" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE
Bloque try-catch en el script de canalización de Jenkins
En el estilo declarativo de canalización, por lo que no debe utilizar bloques try / catch (que son para canalizaciones con script). La clave es poner try ... catch en un bloque de script en sintaxis declarativa de canalización. Entonces funcionará. Esto podría ser útil si desea decir que continúe la ejecución de la canalización a pesar de la falla (por ejemplo, la prueba falló, aún necesita informes)
NOTA: sh 'comando no válido' -> Puede fallar la etapa aunque sea parte del script.
script {
try {
sh 'do your stuff'
} catch (Exception e) {
sh 'Handle the exception!'
}
}
try {
sh 'might fail'
echo 'Succeeded!'
} catch (err) {
echo "Failed: ${err}"
} finally {
sh './tear-down.sh'
}
pipeline {
agent any
stages {
stage('Validate Fail fast') {
failFast true
parallel {
stage('stage A') {
steps {
echo 'stage A started'
sleep 5
script {
try {
sh 'I_AM_NOT_VALID_CMD'
} catch (Exception e) {
sh 'EVEN_I_AM_INVALID_2_FAIL_THIS_BUILD!'
}
}
echo 'stage A Ended'
}
}
stage('stage B') {
steps {
echo 'stage B started'
sleep 10
echo 'stage B Ended'
}
}
stage('stage C') {
steps {
echo 'stage C started'
echo 'stage C Ended'
}
}
}
}
stage('final stage sequential') {
steps {
script {
echo "The complete run!"
}
}
}
}
}
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/ErrorHandling
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Validate Fail fast)
[Pipeline] parallel
[Pipeline] { (Branch: stage A)
[Pipeline] { (Branch: stage B)
[Pipeline] { (Branch: stage C)
[Pipeline] stage
[Pipeline] { (stage A)
[Pipeline] stage
[Pipeline] { (stage B)
[Pipeline] stage
[Pipeline] { (stage C)
[Pipeline] echo
stage A started
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
stage B started
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] echo
stage C started
[Pipeline] echo
stage C Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] script
[Pipeline] {
[Pipeline] sh
+ I_AM_NOT_VALID_CMD
/Users/Shared/Jenkins/Home/workspace/ErrorHandling@tmp/durable-5fc28a9a/script.sh: line 1: I_AM_NOT_VALID_CMD: command not found
[Pipeline] sh
+ 'EVEN_I_AM_INVALID_2_FAIL_THIS_BUILD!'
/Users/Shared/Jenkins/Home/workspace/ErrorHandling@tmp/durable-5e73fa36/script.sh: line 1: EVEN_I_AM_INVALID_2_FAIL_THIS_BUILD!: command not found
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage A
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage B
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] stage
[Pipeline] { (final stage sequential)
Stage "final stage sequential" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] End of Pipeline
ERROR: script returned exit code 127
Finished: FAILURE
https://support.cloudbees.com/hc/en-us/articles/218554077-How-to-set-current-build-result-in-Pipeline
currentBuild.result = 'FAILURE'
This will not stop the executions.
¿Cómo manipular el resultado de la compilación de un trabajo de canalización de Jenkins?
por diseño, "el resultado solo puede empeorar, de lo contrario el conjunto se ignora" -> @see setResult () @ https://github.com/jenkinsci/jenkins/blob/213363d387736874f1d14d83e57347f757f3ed4f/core/src/main/java/hudson/model /Run.java#L462-L466
pipeline {
agent any
stages {
stage('Validate Fail fast') {
failFast true
parallel {
stage('stage A') {
steps {
echo 'stage A started'
sleep 5
script {
currentBuild.result = 'FAILURE'
}
echo "RESULT: ${currentBuild.result}"
echo 'stage A Ended'
}
}
stage('stage B') {
steps {
echo 'stage B started'
sleep 10
echo 'stage B wakeup'
script {
currentBuild.result = 'FAILURE'
}
echo "RESULT: ${currentBuild.result}"
echo 'stage B Ended'
}
}
stage('stage C') {
steps {
echo 'stage C started'
echo 'stage C Ended'
}
}
}
}
stage('final stage sequential') {
steps {
script {
echo "The complete run!"
}
}
}
}
}
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/ErrorHandling
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Validate Fail fast)
[Pipeline] parallel
[Pipeline] { (Branch: stage A)
[Pipeline] { (Branch: stage B)
[Pipeline] { (Branch: stage C)
[Pipeline] stage
[Pipeline] { (stage A)
[Pipeline] stage
[Pipeline] { (stage B)
[Pipeline] stage
[Pipeline] { (stage C)
[Pipeline] echo
stage A started
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
stage B started
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] echo
stage C started
[Pipeline] echo
stage C Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline]
[Pipeline] echo
RESULT: FAILURE
[Pipeline] echo
stage A Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] echo
stage B wakeup
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline]
[Pipeline] echo
RESULT: FAILURE
[Pipeline] echo
stage B Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] stage
[Pipeline] { (final stage sequential)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
The complete run!
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] End of Pipeline
Finished: FAILURE
¿Cómo lanzar una excepción en la tubería de Jenkins?
Lanzar una excepción no es una salida uniforme.
pipeline {
agent any
stages {
stage('Validate Fail fast') {
failFast true
parallel {
stage('stage A') {
steps {
echo 'stage A started'
sleep 5
script {
throw new Exception()
}
echo "RESULT: ${currentBuild.result}"
echo 'stage A Ended'
}
}
stage('stage B') {
steps {
echo 'stage B started'
sleep 10
echo 'stage B wakeup'
echo "RESULT: ${currentBuild.result}"
echo 'stage B Ended'
}
}
stage('stage C') {
steps {
echo 'stage C started'
echo 'stage C Ended'
}
}
}
}
stage('final stage sequential') {
steps {
script {
echo "The complete run!"
}
}
}
}
}
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/ErrorHandling
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Validate Fail fast)
[Pipeline] parallel
[Pipeline] { (Branch: stage A)
[Pipeline] { (Branch: stage B)
[Pipeline] { (Branch: stage C)
[Pipeline] stage
[Pipeline] { (stage A)
[Pipeline] stage
[Pipeline] { (stage B)
[Pipeline] stage
[Pipeline] { (stage C)
[Pipeline] echo
stage A started
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
stage B started
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] echo
stage C started
[Pipeline] echo
stage C Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] script
[Pipeline] {
Scripts not permitted to use new java.lang.Exception. Administrators can decide whether to approve or reject this signature.
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage A
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage B
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] stage
[Pipeline] { (final stage sequential)
Stage "final stage sequential" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] End of Pipeline
Also: org.jenkinsci.plugins.workflow.steps.FlowInterruptedException
at org.jenkinsci.plugins.workflow.cps.CpsBodyExecution.cancel(CpsBodyExecution.java:253)
at org.jenkinsci.plugins.workflow.steps.BodyExecution.cancel(BodyExecution.java:76)
at org.jenkinsci.plugins.workflow.cps.steps.ParallelStepExecution.stop(ParallelStepExecution.java:67)
at org.jenkinsci.plugins.workflow.cps.steps.ParallelStep$ResultHandler$Callback.checkAllDone(ParallelStep.java:147)
at org.jenkinsci.plugins.workflow.cps.steps.ParallelStep$ResultHandler$Callback.onFailure(ParallelStep.java:134)
at org.jenkinsci.plugins.workflow.cps.CpsBodyExecution$FailureAdapter.receive(CpsBodyExecution.java:361)
at com.cloudbees.groovy.cps.impl.ThrowBlock$1.receive(ThrowBlock.java:68)
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.lang.Exception
at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectNew(StaticWhitelist.java:271)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onNewInstance(SandboxInterceptor.java:174)
at org.kohsuke.groovy.sandbox.impl.Checker$3.call(Checker.java:200)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedConstructor(Checker.java:205)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.constructorCall(SandboxInvoker.java:21)
at WorkflowScript.run(WorkflowScript:12)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:97)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixName(FunctionCallBlock.java:78)
at jdk.internal.reflect.GeneratedMethodAccessor188.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
at com.cloudbees.groovy.cps.Next.step(Next.java:83)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:129)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:186)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:370)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:93)
at
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Finished: FAILURE
¿Cómo lanzar una excepción en la tubería de Jenkins?
node { try { error 'Test error' } catch (ex) { echo 'Error handled' } }
error
puede realizar las etapas paralelas del pipeline para dejar de ejecutarlo.
El siguiente unstable
comando ' ' es similar a configurar currentBuild.result = 'UNSTABLE
'.
Esto no detendrá las ejecuciones.
script {
unstable 'unstable'
}
pipeline {
agent any
stages {
stage('Validate Fail fast') {
failFast true
parallel {
stage('stage A') {
steps {
echo 'stage A started'
sleep 5
script {
error 'Test error'
}
echo "RESULT: ${currentBuild.result}"
echo 'stage A Ended'
}
}
stage('stage B') {
steps {
echo 'stage B started'
sleep 10
echo 'stage B wakeup'
echo "RESULT: ${currentBuild.result}"
echo 'stage B Ended'
}
}
stage('stage C') {
steps {
echo 'stage C started'
echo 'stage C Ended'
}
}
}
}
stage('final stage sequential') {
steps {
script {
echo "The complete run!"
}
}
}
}
}
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/ErrorHandling
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Validate Fail fast)
[Pipeline] parallel
[Pipeline] { (Branch: stage A)
[Pipeline] { (Branch: stage B)
[Pipeline] { (Branch: stage C)
[Pipeline] stage
[Pipeline] { (stage A)
[Pipeline] stage
[Pipeline] { (stage B)
[Pipeline] stage
[Pipeline] { (stage C)
[Pipeline] echo
stage A started
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
stage B started
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] echo
stage C started
[Pipeline] echo
stage C Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] script
[Pipeline] {
[Pipeline] error
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage A
[Pipeline] }
[Pipeline]
[Pipeline] }
Failed in branch stage B
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] stage
[Pipeline] { (final stage sequential)
Stage "final stage sequential" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] End of Pipeline
ERROR: Test error
Finished: FAILURE
https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-catcherror-code-catch-error-and-set-build-result
catchError {
sh 'might fail'
}
Esto es equivalente a configurar currentBuild.result = 'FAILURE'
Esto no detendrá las ejecuciones.
pipeline {
agent any
stages {
stage('Validate Fail fast') {
failFast true
parallel {
stage('stage A') {
steps {
echo 'stage A started'
sleep 5
script {
catchError {
sh 'might fail'
}
}
echo "RESULT: ${currentBuild.result}"
echo 'stage A Ended'
}
}
stage('stage B') {
steps {
echo 'stage B started'
sleep 10
echo 'stage B wakeup'
echo "RESULT: ${currentBuild.result}"
echo 'stage B Ended'
}
}
stage('stage C') {
steps {
echo 'stage C started'
echo 'stage C Ended'
}
}
}
}
stage('final stage sequential') {
steps {
script {
echo "The complete run!"
}
}
}
}
}
Started by user admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /Users/Shared/Jenkins/Home/workspace/ErrorHandling
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Validate Fail fast)
[Pipeline] parallel
[Pipeline] { (Branch: stage A)
[Pipeline] { (Branch: stage B)
[Pipeline] { (Branch: stage C)
[Pipeline] stage
[Pipeline] { (stage A)
[Pipeline] stage
[Pipeline] { (stage B)
[Pipeline] stage
[Pipeline] { (stage C)
[Pipeline] echo
stage A started
[Pipeline] sleep
Sleeping for 5 sec
[Pipeline] echo
stage B started
[Pipeline] sleep
Sleeping for 10 sec
[Pipeline] echo
stage C started
[Pipeline] echo
stage C Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] script
[Pipeline] {
[Pipeline] catchError
[Pipeline] {
[Pipeline] sh
+ might fail
/Users/Shared/Jenkins/Home/workspace/ErrorHandling@tmp/durable-2b5ebe28/script.sh: line 1: might: command not found
[Pipeline] }
ERROR: script returned exit code 127
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] echo
RESULT: FAILURE
[Pipeline] echo
stage A Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline] echo
stage B wakeup
[Pipeline] echo
RESULT: FAILURE
[Pipeline] echo
stage B Ended
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] stage
[Pipeline] { (final stage sequential)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
The complete run!
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] }
[Pipeline]
[Pipeline] End of Pipeline
Finished: FAILURE