Reputation: 1505
in the following code:
private fun executeCognitoRequest(result: MethodChannel.Result, block: suspend CoroutineScope.() -> Any?) {
try {
CoroutineScope(Dispatchers.Default).launch {
val requestResult = block()
withContext(Dispatchers.Main) {
result.success(requestResult)
}
}
} catch (exception: Exception) {
val cognitoErrorType = CognitoErrorType.getByException(exception)
result.error(cognitoErrorType.code, null, null)
}
}
if the call to block
throws, will it be caught?
Upvotes: 1
Views: 440
Reputation: 200168
It will be caught, but the problem with your code is that you violate the principles of structured concurrency and launch a coroutine in the GlobalScope
. So if you test your code from a main function like this:
fun main() {
runBlocking {
executeCognitoRequest(MethodChannel.Result()) {
funThatThrows()
}
}
}
the whole program will end before the coroutine has completed execution.
This is how you should write your function:
private fun CoroutineScope.executeCognitoRequest(
result: MethodChannel.Result,
block: suspend CoroutineScope.() -> Any?
) {
try {
launch(Dispatchers.IO) {
val requestResult = block()
withContext(Dispatchers.Main) {
result.success(requestResult)
}
}
} catch (exception: Exception) {
val cognitoErrorType = CognitoErrorType.getByException(exception)
result.error(cognitoErrorType.code, null, null)
}
}
Now your function is an extension on CoroutineScope
and launch
is automatically called with that receiver. Also, for blocking IO calls you shouldn't use the Default
but the IO
dispatcher.
However, I find your higher-level design weird, you start from blocking code and turn it into async, callback-oriented code. Coroutines are there to help you get rid of callbacks.
Upvotes: 1