Generalidades

Manejo de excepciones en callbackFlow con Kotlin | Por Florent Blot | Mar 2022

Manejo de excepciones en callbackFlow con Kotlin Por Florent
fotógrafo baz andersen existe sin salpicaduras

en nuestra aplicación de Android @jeeve, tratamos de usar Kotlin Flow para manejar las llamadas de Websockets para nuevos mensajes instantáneos.Utilizamos principalmente callbackFlow Los generadores emiten y reciben datos. El constructor es fácil de usar y se mantiene vivo mientras escucha eventos de socket.

Pero es difícil para nosotros detectar excepciones inesperadas en este constructor.incluso uno try/catch Las cláusulas sobre los recolectores de flujo son inútiles. Necesitamos manejar adecuadamente las excepciones inesperadas en este generador de procesos.

Supongamos que tenemos un proceso simple numbers() recolectando números enteros de 0 a 2, pero al final, algo sucedió y arrojó una excepción inesperada, por check Las funciones son las siguientes:

Manejo de excepciones en callbackFlow con Kotlin Por Florent

recopilados cuando aplicamos catch operador para manejar las excepciones.Este operador captura solo excepciones aguas arriba (todas las excepciones operador desde arriba y no más bajo que eso).

1646321811 664 Manejo de excepciones en callbackFlow con Kotlin Por Florent

Entonces usamos onEach y launchIn reemplazar collect determinar solo catch cogerá Cada Una excepción que ocurrió en la corriente ascendente.

Cuando se recopila, da el siguiente resultado:

Getting: 0
Getting: 1
Caught: java.lang.IllegalStateException: Check failed

Los números se recopilan bien e incluso se maneja la excepción lanzada.

¿Qué sucede si la excepción no se lanza en el generador sino en la devolución de llamada? Vamos a averiguar.

Necesitamos crear una devolución de llamada simple que nos dé el nuevo valor a emitir:

1646321811 735 Manejo de excepciones en callbackFlow con Kotlin Por Florent

rediseñamos numbers() Utilice esta nueva devolución de llamada:

1646321812 382 Manejo de excepciones en callbackFlow con Kotlin Por Florent

Echemos un vistazo al código anterior:

  • todavía usamos nuestro callbackFlow El generador devuelve un Flow.
  • Esta var callback Nuestro nuevo oyente se define: llamar de vuelta.
  • nosotros cubrimos onNextNumber recibir un nuevo entero i Devolución de llamada desde arriba.
  • Esta check La función verifica que el entero recibido sea estrictamente menor que 2.Si no, lanzará un IllegalStateException (Al igual que nuestro primer fragmento, simulará una excepción inesperada).
  • Si el proceso continúa, le enviamos el nuevo entero trySend.
  • y awaitClose Mantenga el tráfico en marcha. Es necesario mantener la transmisión abierta y limpiar los recursos cuando haya terminado, evitando pérdidas de memoria.

Finalmente, gracias repeat función, enviamos 0 a 2 (nuestro índice it a continuación) a través de nuestra devolución de llamada:

1646321812 511 Manejo de excepciones en callbackFlow con Kotlin Por Florent

Ahora, usando el mismo colector que llamamos antes, obtenemos el siguiente resultado:

Getting: 0 
Getting: 1
AndroidRuntime: FATAL EXCEPTION: main
Process: app, PID: 8141
java.lang.IllegalStateException: Check failed.
at MainActivity$numbers$1$1.onNextNumber(MainActivity.kt:40)
at MainActivity$onCreate$3.invokeSuspend(MainActivity.kt:32)
at BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
...

Espera… 😱 La aplicación falla inesperadamente a pesar de nuestra aplicación catch operador.Además, terminamos en la misma situación. try/catch Cláusula alrededor del flujo.excepción en Devolución de llamada no procesada.

Nuestro primer proceso detectó con éxito la excepción, mientras que el segundo proceso no. ¿Por qué?

Esta block Pausa de Process Builder gama de productoreses una extensión Alcance de la rutinaEsta interfaz define un alcance para la nueva corrutina y, si ocurre una excepción, este alcance la manejará.Entonces, en nuestro primer fragmento, se arroja al alcance del generador de flujo y lo usa nuestro catch operador.

Pero en nuestro segundo fragmento, se lanza la excepción en Oyente de devolución de llamada. El alcance ya no es el alcance de la rutina, por lo que el proceso no puede manejarlo. El manejo de tales excepciones es responsabilidad de la devolución de llamada.

vamos a girar repeat función y try/catch cláusula para verificar:

1646321812 768 Manejo de excepciones en callbackFlow con Kotlin Por Florent

Recójalo ahora para confirmarlo, imprima el registro de devolución de llamada anterior:

Getting 0
Getting 1
Callback caught: java.lang.IllegalStateException: Check failed.

¿Cómo arrojamos excepciones en el ámbito correcto y activamos nuestro catch ¿Qué pasa con el operador?

ProducerScope también es enviar canalAsí que bajo el capó, numbers() utilizar una canalPara propagar la excepción, tenemos dos opciones: quitar el ámbito de su rutina o cerrar su canal.

Se puede usar el rango de cancelación cancelEs una extensión de CoroutineScope que también cancela su trabajo y todos sus hijos.lanza un Cancelar excepción Podemos especificar un motivo o incluir un mensaje con una excepción específica.

fun CoroutineScope.cancel(cause: CancellationException? = null)fun CoroutineScope.cancel(message: String, cause: Throwable? = null)

Por otro lado, tenemos closeEnvía un «token de cierre» especial por el canal, con un motivo opcional. Podemos agregar una excepción específica como un motivo no nulo. Esto cerrará el canal, por lo que llamará a la finalización del proceso.

abstract fun close(cause: Throwable? = null): Boolean

Se comportan de la misma manera, por lo que el proceso se completará de manera anormal. catch y onCompletion sera llamado. Sin embargo, la eliminación del ámbito por un motivo se usa principalmente para proporcionar un motivo con fines de depuración.Si prefiere manejar un tipo específico de excepción, debe usar close.

Entonces, con close (o cancel), tenemos la capacidad de propagar la excepción al alcance correcto.

Solo necesitamos rodear nuestro bloque de devolución de llamada con un try/catch cláusula y cierre el canal con un motivo no nulo:

1646321812 873 Manejo de excepciones en callbackFlow con Kotlin Por Florent

El proceso de recogernos ahora nos dará:

Getting: 0
Getting: 1
Caught: java.lang.IllegalStateException: Check failed

Al cerrar el canal de forma anormal, ahora podemos activar nuestro catch operador y manejar cualquier error inesperado.

Al llamar a la función scoped o channel, ahora podemos activar nuestra catch Operadores de diferentes gamas. Cada excepción de la devolución de llamada al constructor, incluso dentro del operador de transmisión, será manejada por catch.

Si te ha resultado útil este artículo, ¡no dudes en aplaudir! 👏 Gracias por leer.

LEER  Su primer proyecto de Android Clean MVI | por Seef Kordia | Agosto de 2021

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba