У меня есть руководитель, который запускает некоторые дочерние сопрограммы.
supervisorScope {
aListOfJobs.forEach { job -> launch(handler) { process(job) } }
}
}
Где обработчик — это некоторый обратный вызов для обработки выброшенных исключений из дочерних сопрограмм.
val handler = CoroutineExceptionHandler { _, exception ->
// for some exceptions I should allow the parent job to continue, and others I should not and trigger the cancellation of my parent
}
Кажется, что даже когда обработчик выдает исключение (т.е. я повторно выбрасываю полученное исключение), супервизор не отменяется.
Итак, мой вопрос: каков идиоматический способ разрешить руководителю продолжать работу для одних исключений, но не для других?
Вы не можете сделать это с помощью CoroutineExceptionHandler
, вместо этого вы должны использовать coroutineScope
и try catch
try {
coroutineScope {
aListOfJobs.forEach { job ->
launch {
try {
process(job)
} catch (e: WorkShouldСontinueExceprion) {
}
}
}
}
} catch (e: WorkShouldStopExceprion) {
}
Если ответить: "Какой идиоматический способ разрешить супервизору продолжать работу для одних исключений, но не для других?" Я согласен с @ IR42. Если у нас есть много различных типов исключений, и мы хотели бы игнорировать некоторые из них и не выполнять другие, возможно, будет понятнее отказаться по умолчанию и игнорировать в определенных случаях.
Однако, если в вашем случае вы обычно игнорируете все ошибки, но терпите неудачу в одной или нескольких конкретных (например, в явном исключении «отмена»), вы можете вызвать cancel()
вручную:
supervisorScope {
aListOfJobs.forEach { job ->
launch {
try {
process(job)
} catch (e: AbortException) {
[email protected]("message", e)
throw e
}
}
}
}