maxmello
09/18/2024, 1:48 PM.onEach running (handling rabbitMQ messages). This flow should never complete/stop, except when the whole application goes down. Therefore, I have the inside of the .onEach wrapped by a try-catch block with catching e: Exception.
Inside this code block, I run code that includes Exposed suspended transactions. It can happen that I get expected SQL exceptions, which I also catch, but somehow I always get
kotlinx.coroutines.JobCancellationException: Parent job is Cancelling
Caused by: org.jetbrains.exposed.exceptions.ExposedSQLException
As stated, this exception is catched though, but the flow still completes. So I can only imagine that some code (maybe Exposed code) manually cancels the parent job, right?phldavies
09/18/2024, 1:58 PMsupervisorScope as any child coroutines that fail will propagate that failure to the parent scope and cause cancellation to propagate otherwisegildor
09/19/2024, 2:22 AMmaxmello
09/19/2024, 9:45 AMinsertIntoDatabase call in the snippet below in supervisorScope { … } did fix the problem.
As I realize I am no coroutine expert, I’m not fully sure why, maybe the TransactionScope using the parent coroutine context as its own coroutine context means, its the Flow s coroutine context that is cancelled when an exception inside the suspendedTransaction block occurs?phldavies
09/19/2024, 11:09 AMCancellationException without rethrowing it as doing so will break structured concurrency. If a coroutine fails (that is, throws a non-cancellation exception) then normally the parent coroutine will fail itself and propagate its cancellation to its remaining children. supervisorScope handles child-failure by effectively ignoring it - meaning it will not fail itself when a child failsmaxmello
09/19/2024, 11:33 AMnewSuspendedTransaction takes CoroutineContext? = null as a first optional parameter. When I call newSuspendedTransaction(<http://Dispatchers.IO|Dispatchers.IO>), it behaves identical to when I wrap the code in supervisorScope. So I think the problem was that the TA took the flows coroutine context as its own context, which then cancelled the whole flow on failure of the transaction