------------------------- | Error Handling Demo | |-----------------------| | [Fetch Data] | | | | Status: | | | | Message: | -------------------------
Error handling patterns in Android Kotlin - Mini App: Build & Ship
package com.example.errorhandlingdemo import android.os.Bundle import android.widget.Button import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import kotlin.random.Random class MainActivity : AppCompatActivity() { private lateinit var statusTextView: TextView private lateinit var messageTextView: TextView private lateinit var fetchButton: Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) statusTextView = findViewById(R.id.statusTextView) messageTextView = findViewById(R.id.messageTextView) fetchButton = findViewById(R.id.fetchButton) fetchButton.setOnClickListener { // TODO: Implement error handling when fetching data } } // Simulate a network call that randomly succeeds or throws an exception private fun fetchData(): String { if (Random.nextBoolean()) { return "Data loaded successfully" } else { throw Exception("Network error occurred") } } }
package com.example.errorhandlingdemo import android.os.Bundle import android.widget.Button import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import kotlin.random.Random class MainActivity : AppCompatActivity() { private lateinit var statusTextView: TextView private lateinit var messageTextView: TextView private lateinit var fetchButton: Button private var useRunCatching = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) statusTextView = findViewById(R.id.statusTextView) messageTextView = findViewById(R.id.messageTextView) fetchButton = findViewById(R.id.fetchButton) fetchButton.setOnClickListener { if (useRunCatching) { fetchDataWithRunCatching() } else { fetchDataWithTryCatch() } useRunCatching = !useRunCatching } } private fun fetchDataWithTryCatch() { try { val data = fetchData() statusTextView.text = "Status: Success" messageTextView.text = data } catch (e: Exception) { statusTextView.text = "Status: Error" messageTextView.text = e.message } } private fun fetchDataWithRunCatching() { val result = runCatching { fetchData() } result.onSuccess { data -> statusTextView.text = "Status: Success" messageTextView.text = data }.onFailure { error -> statusTextView.text = "Status: Error" messageTextView.text = error.message } } private fun fetchData(): String { if (Random.nextBoolean()) { return "Data loaded successfully" } else { throw Exception("Network error occurred") } } }
This solution shows two common error handling patterns in Kotlin for Android.
First, try-catch is used in fetchDataWithTryCatch() to catch exceptions from fetchData(). If successful, it updates the UI with success status and data. If an exception occurs, it shows an error status and message.
Second, runCatching is used in fetchDataWithRunCatching(). This Kotlin function wraps the call and returns a Result object. We then use onSuccess and onFailure to handle success and error cases cleanly.
The button toggles between these two methods each time it is clicked, demonstrating both patterns in one screen.
UI updates happen on the main thread because the click listener runs on the main thread by default.
------------------------- | Error Handling Demo | |-----------------------| | [Fetch Data] | | | | Status: Success | | | | Message: | | Data loaded successfully| -------------------------
Practice
try-catch block in Kotlin error handling?Solution
Step 1: Understand the role of
Thetry-catchtryblock contains code that might cause an error, and thecatchblock handles that error.Step 2: Identify the purpose in app safety
Usingtry-catchprevents the app from crashing by catching exceptions and allowing graceful handling.Final Answer:
To catch exceptions and prevent app crashes -> Option DQuick Check:
Error handling = catch exceptions [OK]
- Thinking try-catch speeds up code
- Confusing try-catch with UI styling
- Believing try-catch creates variables
Solution
Step 1: Recall Kotlin catch syntax
Kotlin requires parentheses around the exception variable with its type in the catch block.Step 2: Compare options to correct syntax
Only try { /* code */ } catch (e: Exception) { /* handle */ } usescatch (e: Exception)which is the correct Kotlin syntax.Final Answer:
try { /* code */ } catch (e: Exception) { /* handle */ } -> Option CQuick Check:
Correct catch syntax = try { /* code */ } catch (e: Exception) { /* handle */ } [OK]
- Omitting parentheses in catch
- Using 'except' instead of 'catch'
- Wrong order of exception and variable
fun main() {
try {
val result = 10 / 0
println("Result: $result")
} catch (e: ArithmeticException) {
println("Caught an arithmetic error")
} finally {
println("Done")
}
}Solution
Step 1: Identify the error in try block
Dividing 10 by 0 causes anArithmeticException.Step 2: Check catch and finally behavior
The catch block catches the exception and prints the message. The finally block always runs and prints "Done".Final Answer:
Caught an arithmetic error\nDone -> Option AQuick Check:
Catch runs on error, finally always runs [OK]
- Assuming division by zero prints result
- Ignoring finally block output
- Thinking app crashes without catch
try {
val text: String = null
println(text.length)
} catch (e: NullPointerException) {
println("Null pointer caught")
}Solution
Step 1: Analyze null assignment in Kotlin
Kotlin does not allow assigning null to a non-nullable type without using nullable type syntax.Step 2: Check compilation rules
Assigningnulltoval textwithout declaring it nullable causes a compile-time error.Final Answer:
Code will not compile due to null assignment -> Option AQuick Check:
Null safety requires nullable types [OK]
- Assuming NullPointerException is caught at runtime
- Ignoring Kotlin's null safety rules
- Thinking code runs without error
Solution
Step 1: Understand resource cleanup needs
Files must be closed to free resources, even if an error happens during reading.Step 2: Use finally block for guaranteed execution
Thefinallyblock runs no matter what, so closing the file there ensures cleanup.Step 3: Combine with try-catch for error handling
Try-catch handles errors, finally ensures file closure regardless of success or failure.Final Answer:
Use try-catch-finally and close file in finally -> Option BQuick Check:
Finally block ensures cleanup [OK]
- Closing file only in try block
- Ignoring finally block for cleanup
- Using finally without try-catch
Ready to prove it?
Pass the test and this pattern moves unknown
