Apparently I have failed to understand the logic of exception handling with kotlin coroutines. Could you please help me? On my Android app I have a button which fires the fetch function.
This function does 3 things:
retrieves a json file from a server (getRequest) - might fail
Processes the json file (processJSON) and stores 4 values temporarily inside the instance of the class Departures (departures). - might fail for another reason
populates 4 TextView with those values. (uiUpdate) I would like all of those fields to be populated with one understandable error message generated by the catch clauses of these failed functions. How can I achieve this?
fun fetch(stopID: String, attr: String, value: String) { lifecycleScope.launch(Dispatchers.IO) { try { val result = getRequest(stopID) val departures = processJSON(result, attr, value) withContext(Dispatchers.Main) {uiUpdate(stopID, departures)} } catch (e: Exception) { } } }
If I remove the try-catch here, the app crashes in case of an exception. If I put the uiUpdate into the shown catch clause it crashes again.
CodePudding user response:
By default lifecycleScope
uses Dispatchers.Main.immediate
dispatcher. You can remove Dispatchers.IO
from passing it to lifecycleScope.launch
and just call suspend
functions, wrapped into try-catch
:
fun fetch(stopID: String, attr: String, value: String) = lifecycleScope.launch {
try {
val result = getRequest(stopID)
val departures = processJSON(result, attr, value)
uiUpdate(stopID, departures)
} catch (e: Exception) {
// You can update UI here as well
}
}
CodePudding user response:
Thank you Sergey! The following function really does what I intended to achieve. I removed the try-catch from inside the functions and added the respective @Throws expressions before the declaration of these functions.
fun fetch(stopID: String, attr: String, value: String) {
lifecycleScope.launch(Dispatchers.Default) {
try {
val result = getRequest(stopID)
val departures = processJSON(result, attr, value)
withContext(Dispatchers.Main) {uiUpdate(stopID, departures)}
} catch (e: UnknownHostException) {
withContext(Dispatchers.Main) {uiUpdate(stopID, Departures("Error2","Error2"))}
} catch (e: JSONException) {
withContext(Dispatchers.Main) {uiUpdate(stopID, Departures("Error3","Error3"))}
} catch (e: Exception) {
withContext(Dispatchers.Main) {uiUpdate(stopID, Departures("Error4","Error4"))}
}
}
}