Estoy refactorizando una aplicación para reactivar el paradigma usando RxJava. Lo estoy haciendo paso a paso, así que necesito usar toBlocking() en algunos casos para respetar las interfaces, por el momento. ¿Cómo puedo manejar un error cuando uso toBlocking() ?
Antes tenia algo asi:
public List<Employee> getEmployees() { try { return repository.getEmployees(); } catch(Exception e) { throw new MyCustomException(); } } Ahora, el repositorio tiene una interfaz reactiva (devuelve Observable<List<Employee>> ), así que estoy haciendo esto:
public List<Employee> getEmployees() { return repository.getEmployees().toBlocking().single(); } La suscripción a repository.getEmployees() puede devolver un error Observable . Mi pregunta es: ¿cómo puedo manejar este error manteniéndolo bloqueado?
Descubrí un método singleOrDefault() , pero algo como singleOrThrow(new MyCustomException()) estaría bien.
No puede hacer eso, deberá envolverlo con el bloque try/catch, toBlocking() transforma el Observable en BlockingObservable , que no es exactamente un bloque reactivo, más como una colección elegante, ahora carece del poder de componer Observables, operadores, controlando el subproceso/paralelismo, y la construcción básica de la API asíncrona, que tiene incorporado el manejo de errores ( onError() )
Eso es lo que dicen los documentos sobre BlockingObservable :
Puede ser útil para propósitos de prueba y demostración, pero generalmente es inapropiado para aplicaciones de producción (si cree que necesita usar un BlockingObservable, esto suele ser una señal de que debe repensar su diseño).
Entonces, ¿cuál es el punto de actuar con el bloqueo observable? si no puede cambiar la interfaz a Observable , entonces probablemente se pierda todo el sentido de usar Rx y Observable , que es (idealmente) abstraer cada operación basada en eventos en el sistema, y luego poder usar el poder de Operadores/Composición/Gestión asíncrona y construcción de flujos de eventos en su sistema.
Si simplemente envuelve alguna operación de API con Observable y luego la devuelve al mundo no reactivo, entonces el consumidor de la API no puede disfrutar de todos los beneficios de Rx antes mencionados.
Entonces, creo que debería reconsiderar cuál es el propósito de hacer eso y cuál es su objetivo final, puede considerar reemplazar el enfoque Reactivo en algunos lugares de su sistema para comenzar.
Tenemos otra opción para manejar el error usando el método variant para manejar el error como onErrorReturn ...
public List<Employee> getEmployees() { return repository.getEmployees().onErrorReturn{ //Do something //Then return value in case error happened }.toBlocking().single(); }Su MyCustomException está envuelta en RuntimeException por Rx, por lo que debe capturar RuntimeException y luego llamar a getCuase() para obtener MyCustomException como se muestra a continuación.
public List<Employee> getEmployees() { try { return repository.getEmployees().toBlocking().single(); } catch (RuntimeException e) { MyCustomException myCustomException = e.getCause(); if (e != null) { // caught MyCustomException } } }