É razoável para lançar uma exceção a partir de um método assíncrono?

Miguel Gamboa:

Desenvolvimento em Java um método assíncrono com um CompletableFuturetipo 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 AsynchronousChannele 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?

Pedro Felix :

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:

  1. exceções "síncrono", onde o método termina a uma exceção sendo lançada.
  2. 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 asyncfunção via retornou Task/ Promise, mesmo para exceções lançadas antes do primeiro await, e nunca por acabar com a asyncchamada de função com uma exceção.

O mesmo também é verdadeiro para coroutines de KOTLIN, mesmo quando se usa o Unconfineddespachante

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 mainsegmento, no entanto launchtermina com uma adequada Job.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=180730&siteId=1
Recomendado
Clasificación