mirror of
https://github.com/corda/corda.git
synced 2025-06-14 05:08:18 +00:00
CORDA-3217 and CORDA-3195 Various bits arond SQL exceptions and flow hospital (#2605)
* Unwrap rx.OnErrorNotImplementedException so the hospital can handle the cause appropriately * Add db failure cordapp * Renamed folders to avoid ambiguity in gradle * Add integration test for exception hospitalisation when thrown from an RX observable. * Make the test slightly cleaner * Fix the schema to actually match the requirements for my custom state. Thanks a bunch, H2. * Switch test to use SqlException base class. * Schedule error event if we detect that a commit or db flush has thrown (forcing the flow to error even if customer code then goes ahead to swallow the exception) * Revert change to schedule extra error * Add more tests for edge case with DB exceptions, changed CorDapp to suppor this an hook in the flow hospital * Warning about unsubscribe Check state transitioned from clean to error for hospital admission. * Match the test to our actual expectations * Revert "Revert change to schedule extra error" This reverts commit 43d47937 * Prevent suppression of errors arising in `transaction()` and `jdbcConnection()` * Test for SqlException caught trying to escape from recordTransaction and suppressed outside being intercepted. * More tests for various error/catch combinations * Clean up and comments * Code reformat * Fix test compilation
This commit is contained in:
committed by
LankyDan
parent
9b169df2b8
commit
1f71b071aa
@ -20,6 +20,7 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import javax.persistence.AttributeConverter
|
||||
import javax.persistence.PersistenceException
|
||||
import javax.sql.DataSource
|
||||
|
||||
/**
|
||||
@ -98,7 +99,8 @@ class CordaPersistence(
|
||||
cacheFactory: NamedCacheFactory,
|
||||
attributeConverters: Collection<AttributeConverter<*, *>> = emptySet(),
|
||||
customClassLoader: ClassLoader? = null,
|
||||
val closeConnection: Boolean = true
|
||||
val closeConnection: Boolean = true,
|
||||
val errorHandler: (t: Throwable) -> Unit = {}
|
||||
) : Closeable {
|
||||
companion object {
|
||||
private val log = contextLogger()
|
||||
@ -189,10 +191,18 @@ class CordaPersistence(
|
||||
}
|
||||
|
||||
fun createSession(): Connection {
|
||||
// We need to set the database for the current [Thread] or [Fiber] here as some tests share threads across databases.
|
||||
_contextDatabase.set(this)
|
||||
currentDBSession().flush()
|
||||
return contextTransaction.connection
|
||||
try {
|
||||
// We need to set the database for the current [Thread] or [Fiber] here as some tests share threads across databases.
|
||||
_contextDatabase.set(this)
|
||||
currentDBSession().flush()
|
||||
return contextTransaction.connection
|
||||
} catch (sqlException: SQLException) {
|
||||
errorHandler(sqlException)
|
||||
throw sqlException
|
||||
} catch (persistenceException: PersistenceException) {
|
||||
errorHandler(persistenceException)
|
||||
throw persistenceException
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,10 +230,18 @@ class CordaPersistence(
|
||||
recoverAnyNestedSQLException: Boolean, statement: DatabaseTransaction.() -> T): T {
|
||||
_contextDatabase.set(this)
|
||||
val outer = contextTransactionOrNull
|
||||
return if (outer != null) {
|
||||
outer.statement()
|
||||
} else {
|
||||
inTopLevelTransaction(isolationLevel, recoverableFailureTolerance, recoverAnyNestedSQLException, statement)
|
||||
try {
|
||||
return if (outer != null) {
|
||||
outer.statement()
|
||||
} else {
|
||||
inTopLevelTransaction(isolationLevel, recoverableFailureTolerance, recoverAnyNestedSQLException, statement)
|
||||
}
|
||||
} catch (sqlException: SQLException) {
|
||||
errorHandler(sqlException)
|
||||
throw sqlException
|
||||
} catch (persistenceException: PersistenceException) {
|
||||
errorHandler(persistenceException)
|
||||
throw persistenceException
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user