From 44206a0bea4bdca2877be0187c896a73a1ac0e6c Mon Sep 17 00:00:00 2001 From: LankyDan Date: Mon, 21 Oct 2019 12:28:52 +0100 Subject: [PATCH] CORDA-3194 Update flow hospital docs, tidy comment and make exception public --- docs/source/node-flow-hospital.rst | 13 ++++++++++--- .../services/statemachine/ActionExecutorImpl.kt | 2 +- .../statemachine/StateTransitionExceptions.kt | 5 +++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/source/node-flow-hospital.rst b/docs/source/node-flow-hospital.rst index b78dbc2825..28908e6d92 100644 --- a/docs/source/node-flow-hospital.rst +++ b/docs/source/node-flow-hospital.rst @@ -51,7 +51,13 @@ Specifically, there are two main ways a flow is hospitalized: * **Database constraint violation** (``ConstraintViolationException``): This scenario may occur due to natural contention between racing flows as Corda delegates handling using the database's optimistic concurrency control. - As the likelihood of re-occurrence should be low, the flow will actually error and fail if it experiences this at the same point more than 3 times. No intervention required. + If this exception occurs, the flow will retry. After retrying a number of times, the errored flow is kept in for observation. + + * ``SQLTransientConnectionException``: + Database connection pooling errors are dealt with. If this exception occurs, the flow will retry. After retrying a number of times, the errored flow is kept in for observation. + + * All other instances of ``SQLException``: + Any ``SQLException`` that is thrown and not handled by any of the scenarios detailed above, will be kept in for observation after their first failure. * **Finality Flow handling** - Corda 3.x (old style) ``FinalityFlow`` and Corda 4.x ``ReceiveFinalityFlow`` handling: If on the receive side of the finality flow, any error will result in the flow being kept in for observation to allow the cause of the @@ -64,7 +70,8 @@ Specifically, there are two main ways a flow is hospitalized: The time is hard to document as the notary members, if actually alive, will inform the requester of the ETA of a response. This can occur an infinite number of times. i.e. we never give up notarising. No intervention required. - * ``SQLTransientConnectionException``: - Database connection pooling errors are dealt with. If this exception occurs, the flow will retry. After retrying a number of times, the errored flow is kept in for observation. + * **Internal Corda errors**: + Flows that experience errors from inside the Corda statemachine, that are not handled by any of the scenarios details above, will be retried a number of times + and then kept in for observation if the error continues. .. note:: Flows that are kept in for observation are retried upon node restart. diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/ActionExecutorImpl.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/ActionExecutorImpl.kt index a84556db6c..5eba44c31b 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/ActionExecutorImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/ActionExecutorImpl.kt @@ -128,7 +128,7 @@ class ActionExecutorImpl( } catch (e: Exception) { // Catch all exceptions that occur in the [DeduplicationHandler]s (although errors should be unlikely) // It is deemed safe for errors to occur here - // Therefore the current transition should not fail is something does go wrong + // Therefore the current transition should not fail if something does go wrong log.info( "An error occurred executing a deduplication post-database commit handler. Continuing, as it is safe to do so.", e diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/StateTransitionExceptions.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/StateTransitionExceptions.kt index 221dbc0df5..6e78fd5113 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/StateTransitionExceptions.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/StateTransitionExceptions.kt @@ -3,7 +3,8 @@ package net.corda.node.services.statemachine import net.corda.core.CordaException import net.corda.core.serialization.ConstructorForDeserialization -// TODO This exception should not be propagated up to rpc as it suppresses the real exception +// TODO These exceptions should not be propagated up to rpc as they suppress the real exceptions + class StateTransitionException( val transitionAction: Action?, val transitionEvent: Event?, @@ -14,4 +15,4 @@ class StateTransitionException( constructor(exception: Exception): this(null, null, exception) } -internal class AsyncOperationTransitionException(exception: Exception) : CordaException(exception.message, exception) +class AsyncOperationTransitionException(exception: Exception) : CordaException(exception.message, exception)