1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-03-03 15:02:35 +02:00

stageWrapper: new error handling (#1401)

* handlePipelineStepErrors: allow disabling for stages
* update error handling in stages
* move file loading into try catch
* Cleanup DebugReport before test

Apparantly, the same DebugReport instance is loaded
during all Unit Tests. Avoid left-overs from previous
tests.

Co-authored-by: Stephan Aßmus <stephan.assmus@sap.com>
This commit is contained in:
Oliver Nocon 2020-04-15 14:02:41 +02:00 committed by GitHub
parent b9781ce50c
commit bd0eed30ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 29 deletions

View File

@ -226,6 +226,8 @@ class PiperStageWrapperTest extends BasePiperTest {
Throwable caught = null
def executed = false
// Clear DebugReport to avoid left-overs from another UnitTest
DebugReport.instance.failedBuild = [:]
try {
stepRule.step.piperStageWrapper(
@ -242,7 +244,7 @@ class PiperStageWrapperTest extends BasePiperTest {
assertThat(executed, is(true))
assertThat(loggingRule.log, containsString('[piperStageWrapper] Found global interceptor \'test_crashing_extension.groovy\' for test_crashing_extension.'))
assertThat(DebugReport.instance.failedBuild.step, is('test_crashing_extension'))
assertThat(DebugReport.instance.failedBuild.step, is('test_crashing_extension(extended)'))
assertThat(DebugReport.instance.failedBuild.fatal, is('true'))
assertThat(DebugReport.instance.failedBuild.reason, is(caught))
}

View File

@ -29,22 +29,18 @@ void call(Map parameters = [:], body) {
.use()
stageLocking(config) {
// failOnError needs to be set to not harm resilience feature
// if not set to true: failures in mandatory steps will be caught here and neglected
handlePipelineStepErrors(stepName: stageName, stepParameters: parameters, failOnError: true) {
def containerMap = ContainerMap.instance.getMap().get(stageName) ?: [:]
if (Boolean.valueOf(env.ON_K8S) && containerMap.size() > 0) {
DebugReport.instance.environment.put("environment", "Kubernetes")
withEnv(["POD_NAME=${stageName}"]) {
dockerExecuteOnKubernetes(script: script, containerMap: containerMap, stageName: stageName) {
executeStage(script, body, stageName, config, utils, parameters.telemetryDisabled)
}
}
} else {
node(config.nodeLabel) {
def containerMap = ContainerMap.instance.getMap().get(stageName) ?: [:]
if (Boolean.valueOf(env.ON_K8S) && containerMap.size() > 0) {
DebugReport.instance.environment.put("environment", "Kubernetes")
withEnv(["POD_NAME=${stageName}"]) {
dockerExecuteOnKubernetes(script: script, containerMap: containerMap, stageName: stageName) {
executeStage(script, body, stageName, config, utils, parameters.telemetryDisabled)
}
}
} else {
node(config.nodeLabel) {
executeStage(script, body, stageName, config, utils, parameters.telemetryDisabled)
}
}
}
}
@ -151,21 +147,28 @@ private void executeStage(script, originalStage, stageName, config, utils, telem
}
private void callInterceptor(Script script, String extensionFileName, Closure originalStage, String stageName, Map configuration) {
Script interceptor = load(extensionFileName)
if (isOldInterceptorInterfaceUsed(interceptor)) {
echo("[Warning] The interface to implement extensions has changed. " +
"The extension $extensionFileName has to implement a method named 'call' with exactly one parameter of type Map. " +
"This map will have the properties script, originalStage, stageName, config. " +
"For example: def call(Map parameters) { ... }")
interceptor.call(originalStage, stageName, configuration, configuration)
} else {
validateInterceptor(interceptor, extensionFileName)
interceptor.call([
script : script,
originalStage: originalStage,
stageName : stageName,
config : configuration
])
try {
Script interceptor = load(extensionFileName)
if (isOldInterceptorInterfaceUsed(interceptor)) {
echo("[Warning] The interface to implement extensions has changed. " +
"The extension $extensionFileName has to implement a method named 'call' with exactly one parameter of type Map. " +
"This map will have the properties script, originalStage, stageName, config. " +
"For example: def call(Map parameters) { ... }")
interceptor.call(originalStage, stageName, configuration, configuration)
} else {
validateInterceptor(interceptor, extensionFileName)
interceptor.call([
script : script,
originalStage: originalStage,
stageName : stageName,
config : configuration
])
}
} catch (Throwable error) {
if (!DebugReport.instance.failedBuild.step) {
DebugReport.instance.storeStepFailure("${stageName}(extended)", error, true)
}
throw error
}
}