mirror of
https://github.com/corda/corda.git
synced 2025-02-20 09:26:41 +00:00
CORDA-3638: Allow CordaFuture to complete even if an Error is thrown. (#5994)
* Allow CordaFuture to complete even if an Error is thrown. * Allow CordaFuture.flatMap() to notify for failures due to Error.
This commit is contained in:
parent
da3adb40b4
commit
fec2ef2fd3
@ -78,6 +78,7 @@ fun <ELEMENT> CordaFuture<out ELEMENT>.mapError(transform: (Throwable) -> Throwa
|
||||
* But if this future or the transform fails, the returned future's outcome is the same throwable.
|
||||
* In the case where this future fails, the transform is not invoked.
|
||||
*/
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
fun <V, W> CordaFuture<out V>.flatMap(transform: (V) -> CordaFuture<out W>): CordaFuture<W> = CordaFutureImpl<W>().also { result ->
|
||||
thenMatch(success@ {
|
||||
result.captureLater(try {
|
||||
@ -85,6 +86,9 @@ fun <V, W> CordaFuture<out V>.flatMap(transform: (V) -> CordaFuture<out W>): Cor
|
||||
} catch (e: Exception) {
|
||||
result.setException(e)
|
||||
return@success
|
||||
} catch (t: Throwable) {
|
||||
result.setException(t)
|
||||
throw t
|
||||
})
|
||||
}, {
|
||||
result.setException(it)
|
||||
@ -136,11 +140,15 @@ interface ValueOrException<in V> {
|
||||
fun captureLater(f: CordaFuture<out V>) = f.then { capture { f.getOrThrow() } }
|
||||
|
||||
/** Run the given block (in the foreground) and set this future to its outcome. */
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
fun capture(block: () -> V): Boolean {
|
||||
return set(try {
|
||||
block()
|
||||
} catch (e: Exception) {
|
||||
return setException(e)
|
||||
} catch (t: Throwable) {
|
||||
setException(t)
|
||||
throw t
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -160,12 +168,16 @@ internal class CordaFutureImpl<V>(private val impl: CompletableFuture<V> = Compl
|
||||
override fun setException(t: Throwable) = impl.completeExceptionally(t)
|
||||
override fun <W> then(callback: (CordaFuture<V>) -> W) = thenImpl(defaultLog, callback)
|
||||
/** For testing only. */
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
internal fun <W> thenImpl(log: Logger, callback: (CordaFuture<V>) -> W) {
|
||||
impl.whenComplete { _, _ ->
|
||||
try {
|
||||
callback(this)
|
||||
} catch (e: Exception) {
|
||||
log.error(listenerFailedMessage, e)
|
||||
} catch (t: Throwable) {
|
||||
log.error(listenerFailedMessage, t)
|
||||
throw t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user