Lesson 17.1: Simple Explanation of Error Handling in Programming

Bugs and errors in code are inevitable

, so it’s crucial not just to find them but also to handle them properly. If a program doesn’t know how to react to errors, it might just crash unexpectedly. Let’s break down the types of errors and how to manage them effectively.


Checked and Unchecked Exceptions

Errors in Java are divided into two main categories: unchecked exceptions and checked exceptions.

Unchecked Exceptions

Unchecked exceptions are errors that you don’t necessarily have to handle explicitly. If one of these occurs, the program crashes unless you catch and handle it.

Examples:

  • ArithmeticException – division by zero.
  • NullPointerException – trying to access an object that is null.
  • ArrayIndexOutOfBoundsException – accessing an invalid index in an array.
  • StringIndexOutOfBoundsException – accessing an invalid index in a string.

These exceptions inherit from RuntimeException, and the compiler doesn’t force you to handle them. However, ignoring them entirely can lead to program crashes, making debugging harder. It’s usually better to either adjust the logic to prevent such errors or handle them gracefully using try-catch, so you can continue testing and improving your program.


Checked Exceptions

Checked exceptions, on the other hand, must be handled. If you don’t handle them, the code won’t compile. You need to either catch the exception using try-catch or throw it further using throws.

Examples:

  • IOException – errors when working with files.
  • SQLException – database-related errors.
  • FileNotFoundException – trying to open a file that doesn’t exist.

These exceptions inherit from Exception (but not RuntimeException), which means you are required to handle them. Lesson 18: Exception vs. RuntimeException in Java: What’s the Deal?


Error Handling in Action

Handling errors properly ensures that your program doesn’t just crash but instead provides useful feedback and continues running where possible.

Example 1: Division by Zero (Unchecked Exception – Optional Handling)

If your program tries to divide by zero without handling it, it will crash. Here’s how to prevent that:

public class DivisionExample {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // Error: division by zero
        } catch (ArithmeticException e) {
            System.out.println("Error: Cannot divide by zero.");
        }
    }
}

Code Breakdown:

  1. The division is inside a try block.
  2. If an error occurs, the catch block catches the ArithmeticException.
  3. Instead of crashing, the program prints a friendly message and continues running.

What Happens When You Run It?

  1. The program attempts to divide by zero inside try.
  2. A ArithmeticException is triggered.
  3. The try block stops executing, and control jumps to catch.
  4. The program prints: Error: Cannot divide by zero.
  5. The program continues running if there’s more code below.
What is ArithmeticException?
  • It’s part of the Java standard library (java.lang package).
  • It’s a subclass of RuntimeException, making it an unchecked exception.
  • Java does not force you to handle it.
What is e in catch (ArithmeticException e)?
  • It’s a variable storing details about the error.
  • When the exception occurs (10 / 0), it’s automatically passed to e.
  • You can use e.getMessage() to get a description of the error.

Example:

catch (ArithmeticException e) {
    System.out.println("Error: " + e.getMessage());
}

Output:

Error: / by zero

If you want a full error trace for debugging, use:

catch (ArithmeticException e) {
    e.printStackTrace();
}

Example 2: Opening a File (Checked Exception – Must Be Handled)

If a file is missing, your program won’t even compile unless you handle the exception.

import java.io.*;

public class FileExample {
    public static void main(String[] args) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
            System.out.println(reader.readLine());
            reader.close();
        } catch (FileNotFoundException e) {
            System.out.println("Error: File not found.");
        } catch (IOException e) {
            System.out.println("Error reading the file.");
        }
    }
}

How It Works:

  1. The program tries to open data.txt.
  2. If the file doesn’t exist, FileNotFoundException is caught.
  3. If there’s an issue reading the file, IOException is caught.
  4. The compiler requires handling these exceptions because they are checked exceptions.

Advanced Error Handling

In larger applications, handling errors properly is even more critical. Instead of spreading try-catch blocks all over the code, it’s better to centralize error handling using custom exception classes.

Why Use Custom Exceptions?

  • Makes error messages more meaningful.
  • Centralizes error handling for better organization.
  • Allows for better reusability and flexibility in error management.

Steps for Better Error Handling:

  1. Create a custom exception class – Give the error a meaningful name and message.
  2. Throw the exception where needed – When an error condition is detected, throw the exception instead of handling it immediately.
  3. Catch and handle it in a centralized place – Keep the handling logic in one place to maintain clean code.

Key Takeaways

  • Unchecked exceptions (RuntimeException) don’t require handling but may cause crashes.
  • Checked exceptions (Exception, excluding RuntimeException) must be handled, or the program won’t compile.
  • Simple error handling with try-catch helps programs recover gracefully.
  • Advanced error handling involves creating structured ways to manage errors for better scalability.

Proper error handling makes your code more reliable, predictable, and user-friendly, ensuring that your program doesn’t just crash whenever something unexpected happens.

Leave a Reply

Your email address will not be published. Required fields are marked *