jean
10/15/2024, 12:18 PMsuspend fun getMyData(): Either<ApiError, Response> =
Either.catch {
delay(1000)
Response
}.mapLeft {
ApiError
}
fun test() {
val job = scope.launch {
getMyData()
}
job.cancel()
}
Is mapLeft
supposed to catch CancellationException? How can I make it propagate the cancellation rather than giving me a Either.Left?Stylianos Gakis
10/15/2024, 12:24 PMjean
10/15/2024, 12:26 PMStylianos Gakis
10/15/2024, 12:28 PMStylianos Gakis
10/15/2024, 12:29 PMI do get them caught inside the try/catch
Do you now mean an actual try/catch, or Either.catch?
jean
10/15/2024, 12:29 PMCLOVIS
10/15/2024, 2:48 PMEither.catch
will let fatal exceptions pass through, as it shouldjean
10/16/2024, 6:30 AMStylianos Gakis
10/16/2024, 7:33 AMFrom the little tests did, I do get them caught inside the try/catch
So, to confirm, you are now seeing the proper behavior of the cancellation propagating properly all the way through right? I am not sure what you want to catch there exactly. If the coroutine was cancelled, is it from the coroutineScope being cancelled? If so, it means the client is no longer interested in the response anymore. What do you want to try/catch it for, and what will you do with that information? I think some more context on what you're trying to do would be beneficial here 😊
jean
10/17/2024, 7:20 AMEither
CLOVIS
10/17/2024, 7:34 AMWe just need to filter out manually the CancellationException out of the logs.No, that's not enough. Why are the logs able to know about it anyway? If they catch it
CancellationException
, you are creating zombies. You can hide the symptoms, but that doesn't solve the problem, it only makes it harder to debug.
See https://betterprogramming.pub/the-silent-killer-thats-crashing-your-coroutines-9171d1e8f79bStylianos Gakis
10/17/2024, 7:37 AMjean
10/17/2024, 7:57 AMEither.catch
wrapping our ktor calls (they don’t check for any specific errors, they should propagate CancellationExceptions), our codebase has a handleResponseExceptionWithRequest
with this
val clientException = exception as? ClientRequestException ?: throw RestClientError.NetworkError(exception).also {
logOtherExceptions(exception, request, corrId)
}
if (clientException.response.status.isSuccess()) {
throw RestClientError.HttpError(clientException.message, clientException.response.status.value)
}
logClientRequestException(exception, request, corrId)
I’m not sure how a CancellationException go through this. but the ktor documentation doesn’t really specify anything more than what we do for cancelling a request
https://ktor.io/docs/client-requests.html#cancel-request