Multiple Catch Block - Kotlin Tutorial
Kotlin Course / Exception Handling / Multiple Catch Block

Multiple Catch Block

BLUF: Mastering Multiple Catch Block is a fundamental step in modern Android and server-side development. This lesson covers the concise syntax and powerful features of Kotlin that make this concept easy to implement.
Modern Expressive Code: Multiple Catch Block

Kotlin's safety features and expressive syntax reduce boilerplate. See how Multiple Catch Block makes your code cleaner and more reliable in the tutorial below.

When it comes to error handling in programming, being prepared for unexpected situations is crucial. In Kotlin, multiple catch blocks provide a way to handle different exceptions that may arise from a single try block. This feature allows developers to tailor their error responses based on the specific type of exception encountered.

Why Use Multiple Catch Blocks?

Imagine you are designing a program that performs various operations, such as dividing numbers or accessing array elements. Each of these operations can potentially cause different types of errors, such as division by zero or accessing an invalid index in an array. By using multiple catch blocks, you can handle each scenario appropriately, ensuring a smoother user experience and preventing the application from crashing unexpectedly.

When and Where to Use It

  • When performing multiple operations that can throw different types of exceptions.
  • In scenarios where specific error handling is necessary, like logging certain exceptions or providing user-friendly messages.
  • When developing robust applications that need to maintain functionality even when exceptions occur.
  • Concept Breakdown

Kotlin allows the use of multiple catch blocks to handle exceptions. The syntax follows a particular structure:

  1. Try Block: Contains the code that may throw exceptions.
  2. Catch Blocks: Each block handles a specific type of exception. You can have several catch blocks following a single try block.
  3. Finally Block (optional): Executed after the try and catch blocks, regardless of whether an exception occurred.
  4. Why Order Matters

It is essential to order your catch blocks from the most specific to the most general. If you start with a general exception type (like Exception), the specific ones (like ArithmeticException) will never get executed, leading to potential bugs and missed error handling.

Basic Syntax

Here’s the basic structure for using multiple catch blocks in Kotlin:

Example

fun main() {
    try {
        // Code that may throw exceptions
    } catch (e: SpecificExceptionType) {
        // Handle specific exception
    } catch (e: AnotherSpecificExceptionType) {
        // Handle another specific exception
    } catch (e: Exception) {
        // Handle general exceptions
    }
}

Working Examples

Example 1: Handling Division and Array Access

This example demonstrates how to handle two different types of exceptions: division by zero and accessing an invalid index in an array.

Example

fun main() {
    try {
        val numbers = intArrayOf(1, 2, 3)
        val result = 10 / 0 // This will throw ArithmeticException
        println("Division Result: $result")
        println("Array Element: ${numbers[5]}") // This will throw ArrayIndexOutOfBoundsException
    } catch (e: ArithmeticException) {
        println("Error: Division by zero is not allowed.")
    } catch (e: ArrayIndexOutOfBoundsException) {
        println("Error: Attempted to access an invalid index in the array.")
    } catch (e: Exception) {
        println("An unexpected error occurred: ${e.message}")
    }
    println("Code continues after try-catch...")
}

Output:

Output

Error: Division by zero is not allowed.
Code continues after try-catch...

Example 2: File Operations

In this example, we try to read from a file that may not exist, which can cause a FileNotFoundException, and we handle that specifically.

Example

import java.io.File
import java.io.FileNotFoundException

fun main() {
    try {
        val file = File("nonexistent_file.txt")
        val content = file.readText() // This will throw FileNotFoundException
        println("File Content: $content")
    } catch (e: FileNotFoundException) {
        println("Error: The specified file was not found.")
    } catch (e: Exception) {
        println("An unexpected error occurred: ${e.message}")
    }
    println("Continuing execution...")
}

Output:

Output

Error: The specified file was not found.
Continuing execution...

Example 3: User Input Validation

Here we check if a user inputs a valid integer, catching NumberFormatException.

Example

fun main() {
    val userInput = "abc" // Invalid input
    try {
        val number = userInput.toInt() // This will throw NumberFormatException
        println("Input is a valid number: $number")
    } catch (e: NumberFormatException) {
        println("Error: Please enter a valid integer.")
    } catch (e: Exception) {
        println("An unexpected error occurred: ${e.message}")
    }
    println("End of input validation.")
}

Output:

Output

Error: Please enter a valid integer.
End of input validation.

Example 4: Chained Exceptions

Kotlin supports chaining exceptions, allowing you to throw a new exception while wrapping an existing one.

Example

fun main() {
    try {
        throw IllegalArgumentException("Invalid argument!") // Original exception
    } catch (e: IllegalArgumentException) {
        throw RuntimeException("Runtime exception caused by: ${e.message}", e) // Chaining
    } catch (e: Exception) {
        println("Caught exception: ${e.message}")
    }
}

Output:

Output

Caught exception: Runtime exception caused by: Invalid argument!

Common Mistakes

Mistake 1: Order of Catch Blocks

Incorrect Order:

Example

try {
    // Code that may throw exceptions
} catch (e: Exception) {
    // General exception first
} catch (e: ArithmeticException) {
    // Specific exception second
}

Why it's wrong: The specific exception block will never be reached, and you'll miss handling specific errors.

Correct Order:

Example

try {
    // Code that may throw exceptions
} catch (e: ArithmeticException) {
    // Handle specific exception
} catch (e: Exception) {
    // Handle general exceptions
}

Mistake 2: Catching Too Many Exceptions

Avoid catching exceptions you don’t intend to handle. This can make debugging harder and obscure the real issues in your code.

Best Practices

  • Order your catch blocks from the most specific to the most general.
  • Use meaningful messages in your catch blocks to provide better insights into errors.
  • Log exceptions for monitoring and debugging purposes, especially in production environments.
  • Only catch exceptions that you can handle appropriately. Don’t swallow exceptions without proper handling.
  • Practice Exercises

  1. Create a program that accepts user input for two numbers and performs division while handling potential exceptions such as ArithmeticException and NumberFormatException.
  2. Develop a simple file reader that attempts to read a file and handles FileNotFoundException and IOException.
  3. Implement a calculator that can handle different operations (addition, subtraction, division) and includes error handling for invalid inputs and division by zero.

By practicing these exercises, you'll reinforce your understanding of multiple catch blocks and exception handling in Kotlin!

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience