From 696230c3e38ee434e48434adaa9d227086a90b34 Mon Sep 17 00:00:00 2001 From: Rob Zienert Date: Tue, 15 Oct 2019 15:10:01 -0700 Subject: [PATCH] fix(*): Change event & saga root exceptions to nonretryable (#4095) --- .../orchestration/ExceptionClassifier.java | 12 ++++++++---- .../exceptions/AggregateChangeRejectedException.kt | 4 +++- .../event/exceptions/InvalidEventTypeException.kt | 6 +++++- .../event/exceptions/UninitializedEventException.kt | 6 +++++- .../exceptions/SagaFlowActionNotFoundException.kt | 6 +++++- .../saga/exceptions/SagaIntegrationException.kt | 6 +++--- .../SagaMissingRequiredCommandException.kt | 6 +++++- .../saga/exceptions/SagaNotFoundException.kt | 6 +++++- .../saga/exceptions/SagaStateIntegrationException.kt | 8 ++++++-- .../saga/exceptions/SagaSystemException.kt | 2 +- 10 files changed, 46 insertions(+), 16 deletions(-) diff --git a/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/orchestration/ExceptionClassifier.java b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/orchestration/ExceptionClassifier.java index 36ad7b27c6d..7e62bc46d0b 100644 --- a/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/orchestration/ExceptionClassifier.java +++ b/clouddriver-core/src/main/groovy/com/netflix/spinnaker/clouddriver/orchestration/ExceptionClassifier.java @@ -53,6 +53,7 @@ public boolean isRetryable(@Nonnull Exception e) { return Optional.ofNullable(((SpinnakerException) e).getRetryable()).orElse(false); } + boolean retryable = false; try { String dynamicNonRetryableClasses = dynamicConfigService.getConfig( @@ -69,13 +70,16 @@ public boolean isRetryable(@Nonnull Exception e) { .flatMap(Collection::stream) .collect(Collectors.toList()); - return !nonRetryableClasses.contains(e.getClass().getName()); + retryable = !nonRetryableClasses.contains(e.getClass().getName()); + } else { + retryable = !properties.getNonRetryableClasses().contains(e.getClass().getName()); } - return !properties.getNonRetryableClasses().contains(e.getClass().getName()); - } catch (Exception caughtException) { log.error("Unexpected exception while processing retryable classes", caughtException); - return false; } + + log.trace("Evaluated retryable status for {} to '{}'", e.getClass().getName(), retryable); + + return retryable; } } diff --git a/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/AggregateChangeRejectedException.kt b/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/AggregateChangeRejectedException.kt index 95b1c4b2b91..1b2f5a6083c 100644 --- a/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/AggregateChangeRejectedException.kt +++ b/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/AggregateChangeRejectedException.kt @@ -29,5 +29,7 @@ class AggregateChangeRejectedException( "Attempting to save new events against an old aggregate version " + "(version: $aggregateVersion, originatingVersion: $originatingVersion)" ) { - override fun getRetryable() = true + init { + retryable = false + } } diff --git a/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/InvalidEventTypeException.kt b/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/InvalidEventTypeException.kt index f3a862500ed..58a8fba840f 100644 --- a/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/InvalidEventTypeException.kt +++ b/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/InvalidEventTypeException.kt @@ -20,4 +20,8 @@ import com.netflix.spinnaker.kork.exceptions.IntegrationException /** * Thrown when a [SpinnakerEvent] cannot be created. */ -class InvalidEventTypeException(cause: Throwable) : IntegrationException(cause), EventingException +class InvalidEventTypeException(cause: Throwable) : IntegrationException(cause), EventingException { + init { + retryable = false + } +} diff --git a/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/UninitializedEventException.kt b/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/UninitializedEventException.kt index 5ca5a759bab..06e9d820970 100644 --- a/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/UninitializedEventException.kt +++ b/clouddriver-event/src/main/kotlin/com/netflix/spinnaker/clouddriver/event/exceptions/UninitializedEventException.kt @@ -23,4 +23,8 @@ import com.netflix.spinnaker.kork.exceptions.IntegrationException */ class UninitializedEventException : IntegrationException( "Cannot access event metadata before initialization" -), EventingException +), EventingException { + init { + retryable = false + } +} diff --git a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaFlowActionNotFoundException.kt b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaFlowActionNotFoundException.kt index e915d6cc838..1ff9b764730 100644 --- a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaFlowActionNotFoundException.kt +++ b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaFlowActionNotFoundException.kt @@ -22,4 +22,8 @@ import com.netflix.spinnaker.clouddriver.saga.flow.SagaAction */ class SagaFlowActionNotFoundException(sagaAction: Class>) : SagaIntegrationException( "Could not find a SagaAction in flow for ${sagaAction.simpleName}" -) +) { + init { + retryable = false + } +} diff --git a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaIntegrationException.kt b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaIntegrationException.kt index b3600efed00..4e6b63a12c9 100644 --- a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaIntegrationException.kt +++ b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaIntegrationException.kt @@ -28,11 +28,11 @@ open class SagaIntegrationException(message: String, cause: Throwable?) : constructor(message: String) : this(message, null) init { - // Defer to the cause for retryable; but default to retryable if the retryable flag is unavailable. + // Defer to the cause for retryable; default to not retryable if the retryable flag is unavailable. retryable = if (cause is SpinnakerException) { - cause.retryable ?: true + cause.retryable ?: false } else { - true + false } } } diff --git a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaMissingRequiredCommandException.kt b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaMissingRequiredCommandException.kt index d6468dc22dd..a5befc4566a 100644 --- a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaMissingRequiredCommandException.kt +++ b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaMissingRequiredCommandException.kt @@ -19,4 +19,8 @@ package com.netflix.spinnaker.clouddriver.saga.exceptions /** * Thrown when a [Saga] requires a specific [SagaCommand] type, but one does not exist in the [Saga] event log. */ -class SagaMissingRequiredCommandException(message: String) : SagaIntegrationException(message) +class SagaMissingRequiredCommandException(message: String) : SagaIntegrationException(message) { + init { + retryable = false + } +} diff --git a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaNotFoundException.kt b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaNotFoundException.kt index 7ff7c0db64b..092b435165d 100644 --- a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaNotFoundException.kt +++ b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaNotFoundException.kt @@ -19,4 +19,8 @@ package com.netflix.spinnaker.clouddriver.saga.exceptions /** * Thrown when a [Saga] cannot be found but it is expected to already exist. */ -class SagaNotFoundException(message: String) : SagaSystemException(message) +class SagaNotFoundException(message: String) : SagaSystemException(message) { + init { + retryable = false + } +} diff --git a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaStateIntegrationException.kt b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaStateIntegrationException.kt index 909784a36f2..21618818f61 100644 --- a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaStateIntegrationException.kt +++ b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaStateIntegrationException.kt @@ -25,11 +25,15 @@ class SagaStateIntegrationException(message: String) : SagaIntegrationException( fun typeNotFound(expectedType: Class<*>, saga: Saga) = SagaStateIntegrationException( "No SagaEvent present for requested type: ${expectedType.simpleName} (${saga.name}/${saga.id})" - ) + ).also { + it.retryable = false + } fun tooManyResults(expectedType: Class<*>, saga: Saga) = SagaStateIntegrationException( "More than one SagaEvent present for requested type: ${expectedType.simpleName} (${saga.name}/${saga.id})" - ) + ).also { + it.retryable = false + } } } diff --git a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaSystemException.kt b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaSystemException.kt index c86392907de..f11f4835af5 100644 --- a/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaSystemException.kt +++ b/clouddriver-saga/src/main/kotlin/com/netflix/spinnaker/clouddriver/saga/exceptions/SagaSystemException.kt @@ -24,6 +24,6 @@ open class SagaSystemException(message: String, cause: Throwable?) : SystemExcep constructor(message: String) : this(message, null) init { - retryable = true + retryable = false } }