Home > database >  Error handling in Kotlin coroutines - How to display error on the UI?
Error handling in Kotlin coroutines - How to display error on the UI?

Time:01-04

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:

  1. retrieves a json file from a server (getRequest) - might fail

  2. Processes the json file (processJSON) and stores 4 values temporarily inside the instance of the class Departures (departures). - might fail for another reason

  3. 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"))}
             }
        }
    }
  •  Tags:  
  • Related