Desenvolvimento em Java um método assíncrono com um CompletableFuture
tipo de retorno esperamos que o CF resultante para completar normalmente ou, excepcionalmente, dependendo se esse método for bem-sucedido ou não.
No entanto, considere, por exemplo, que o meu método grava a um AsynchronousChannel
e tem uma abertura exceção nesse canal. Ele ainda nem começou a escrever. Então, neste caso, eu estou tenting para apenas deixar o fluxo de exceção para o chamador. Isso está correto?
Embora o chamador terá que lidar com 2 cenários de falha: 1) de exceção, ou 2) promessa rejeitado.
Ou, em alternativa, deve o meu método de captura essa exceção e retornar uma promessa rejeitado em vez disso?
IMO, opção 1) faz com que a API mais difícil de usar porque haverá dois caminhos diferentes para a comunicação de erros:
- exceções "síncrono", onde o método termina a uma exceção sendo lançada.
- excepções "assíncronas", onde o método devolve um CF, que completa com uma excepção. Note que é impossível evitar este caso, porque sempre haverá situações em que os erros são encontrados somente após o caminho assíncrona começou (por exemplo, o tempo limite).
O programador tem agora para garantir tanto a esses dois caminhos são tratados corretamente, em vez de apenas um.
Também é interessante observar que o comportamento tanto para C # e Javascript é sempre relatar as exceções lançadas dentro do corpo de uma async
função via retornou Task
/ Promise
, mesmo para exceções lançadas antes do primeiro await
, e nunca por acabar com a async
chamada de função com uma exceção.
O mesmo também é verdadeiro para coroutines de KOTLIN, mesmo quando se usa o Unconfined
despachante
class SynchronousExceptionExamples {
@Test
fun example() {
log.info("before launch")
val job = GlobalScope.launch(Dispatchers.Unconfined) {
log.info("before throw")
throw Exception("an-error")
}
log.info("after launch")
Thread.sleep(1000)
assertTrue(job.isCancelled)
}
}
vai produzir
6 [main] INFO SynchronousExceptionExamples - before launch
73 [main @coroutine#1] INFO SynchronousExceptionExamples - before throw
(...)
90 [main] INFO SynchronousExceptionExamples - after launch
Nota que a exceção ocorre no main
segmento, no entanto launch
termina com uma adequada Job
.