(jvm-based), while trying to ensure that content s...
# coroutines
d
(jvm-based), while trying to ensure that content specific exceptions don't stop sibling/parent coroutines, I want system exceptions to cancel the stack. It's doing great at the former but blithely continuing on the latter. Here's the skeleton, any 🤦 gotchas you note? The
>>
designates where I expect it to void the
supervisorScope
. (Are there paradigmatic examples of how to void the
supervisorScope
?)
Copy code
supervisorScope {
  accounts.forEach { account ->
    this.ensureActive()
    launch(errorHandler("..")) {
        doit(account)
     }
  }
}

    protected fun errorHandler(msg: String): CoroutineExceptionHandler =
        CoroutineExceptionHandler { context, exception ->
            logger.error(exception) { msg }
            if (exception.fatal() || exception.outOfDiskSpace()) {
>>                context.cancel(CancellationException(null, cause = exception))
            }
        }
e
that's the child's
context
and it's already dead by the time your CEH runs, so
context.cancel()
does nothing
d
So, how can code cancel the
supervisorScope
? In other places I use the following, do they work?
Copy code
supervisorScope {
  accounts.forEach { account ->
    this.ensureActive()
    launch(errorHandler("..")) {
      try {
        doit(account)
       } catch (e: Exception) {
          if (e.fatal() || e.outOfDiskSpace()) {
            this@supervisorScope.cancel("Fatal", e)
          } else { throw e }
       }
     }
  }
}
e
cancelling a child of the SupervisorScope doesn't cancel the SupervisorScope (and thus doesn't propagate to other children either). but if you cancel the SupervisorScope directly then you cancel it and all children
I'm not sure you even want a supervisor scope here anyway?
Copy code
coroutineScope {
  accounts.forEach { account ->
    this.ensureActive()
    launch {
      try {
        doit(account)
      } catch (exception: Exception) {
        if (exception.fatal() || exception.outOfDiskSpace()) {
          throw exception
        }
        // swallow exception
      }
    }
  }
}
d
right, using
try/catch
in place of
supervisorScope
may be better, but why doesn't
supervisorScope
have an override? It's rather dangerous that OOM and other fatal exceptions get swallowed imho
e
same as if you had OOM in another thread, it bubbles up to the CoroutineExceptionHandler or Thread.UncaughtExceptionHandler, which by default just logs it