Pihentagy
08/01/2023, 1:59 PMgetLineById(...) = runBlocking {
Deferred<SomeType> someDeferred = async { dependant.thatCanThrow() }
SomeType? res = someDeferred.awaitOrNull();
}
suspend inline fun <T> Deferred<T>.awaitOrNull(): T? = runCatching { this.await() }.getOrNull()
Shouldn't my awaitOrNull
catch all exceptions and convert them to null?
The problem arises when testing:
@MockkBean
private lateinit var dependent: Dependent
@SpykBean
private lateinit var controller: MainController
every { dependent.thatCanThrow() } throws Exception("omg")
controller.getLineById(...)
then the test just throws the Exception("omg"), seemingly pointing to the line:
every { dependent.thatCanThrow() } throws Exception("omg")
Sam
08/01/2023, 2:03 PMasync
job always propagates to the containing scope (in this case the runBlocking
scope) in addition to being thrown from await
. So I would expect getLineById
to fail if the async job fails.Pihentagy
08/01/2023, 2:06 PMSam
08/01/2023, 2:08 PMasync
job itself, and make it a Deferred<SomeType?>
Pihentagy
08/01/2023, 2:15 PMDeferred<SomeType> someDeferred = async { dependant.thatCanThrow() }
I should write
Deferred<SomeType> someDeferred = async { try { dependant.thatCanThrow() } catch(e: Exception) { null } }
?
Can I write an extension method to make it more compact?Pihentagy
08/01/2023, 2:15 PMasyncOrNull
?Pihentagy
08/01/2023, 2:39 PMpublic fun <T> CoroutineScope.asyncOrNull(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T?> = async(context, start) {
try {
block()
} catch (e: Exception) {
null
}
}
Sam
08/01/2023, 2:48 PM