B2.1.3 Describe how programs use common exception handling techniques.

B2.1.3 Describe how programs use common exception handling techniques. 
• Potential points of failure in a program must include unexpected inputs, resource unavailability, logic errors. 
• The role of exception handling in developing programs 
• Exception handling constructs that effectively manage errors must include try/catch in Java, and try/ except in Python, along with the finally block.

The Big Idea

In real-world programming, not all code runs smoothly. Users may enter invalid data, files may not be found, networks may go down, or bugs may lead to logic errors. These unpredictable or faulty situations are called exceptions.

Exception handling is a structured way for programs to detect, respond to, and recover from such failures—without crashing. It is a vital component of robust software design and plays a central role in error management.


Why Exception Handling Matters

Instead of halting a program when an error occurs, a program with exception handling can:

  • Detect errors automatically at runtime,
  • Respond in a controlled, predefined manner,
  • Recover gracefully or safely terminate.

This improves the stability, security, and usability of software.


Points of Failure in Programs

Programs are vulnerable at several predictable locations. These include:

  1. Unexpected Inputs:
    • A user enters text instead of a number.
    • A string is too short for the expected slicing operation.
  2. Resource Unavailability:
    • A file does not exist when trying to read.
    • A web request fails due to no network.
    • A database connection times out.
  3. Logic Errors:
    • Dividing by zero.
    • Accessing an element outside the bounds of a list or array.
    • Infinite recursion or missing base case in recursion.

Exception Handling Techniques

Python: try / except / finally

try:
    number = int(input("Enter a number: "))
    result = 10 / number
except ValueError:
    print("Invalid input. Please enter an integer.")
except ZeroDivisionError:
    print("Cannot divide by zero.")
finally:
    print("This block always runs.")

Explanation:

  • try: Contains code that might raise an exception.
  • except: Catches and handles specific types of errors.
  • finally: Executes code no matter what—whether an exception was raised or not. Common for cleanup.

Java: try / catch / finally

import java.util.Scanner;

public class Example {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        try {
            int number = Integer.parseInt(sc.nextLine());
            int result = 10 / number;
            System.out.println("Result: " + result);
        } catch (NumberFormatException e) {
            System.out.println("Invalid input. Please enter an integer.");
        } catch (ArithmeticException e) {
            System.out.println("Cannot divide by zero.");
        } finally {
            System.out.println("This block always runs.");
            sc.close();
        }
    }
}

Notes:

  • Java requires specifying the type of exception caught.
  • finally is often used to release resources like closing files or database connections.

Best Practices

  • Catch specific exceptions rather than using a general except: (Python) or catch(Exception e) (Java).
  • Use finally to release resources: close files, network connections, or database links.
  • Avoid silent failures: log exceptions or inform the user clearly.
  • Use exception handling to separate error-handling logic from regular code, improving readability.

Real-World Use Cases

  • Web server: If a request fails, respond with an error page, not a crash.
  • Data parser: Skip corrupt data rows and continue processing.
  • File handling tool: Gracefully inform the user if a file is missing or locked.
  • Financial app: Log and recover from a failed transaction without duplicating it.

 

Here’s a structured list of common Python exceptions that you can catch and handle with try/except.

 

Built-in Python Exceptions (catchable)

General

  • Exception
    Base class for most built-in exceptions. Catching this will handle almost all errors, but avoid overusing as it can hide bugs.
  • BaseException
    Top-level for all exceptions (including SystemExit, KeyboardInterrupt). Rarely caught directly, unless you’re building very low-level error handling.

System-related

  • SystemExit
    Raised when sys.exit() is called. Can be caught to prevent program termination.
  • KeyboardInterrupt
    Raised when the user presses Ctrl+C. Commonly caught to allow graceful shutdown.
  • GeneratorExit
    Raised when a generator’s close() method is called.

Arithmetic Errors

  • ArithmeticError
    Base class for arithmetic errors.
  • ZeroDivisionError
    Division or modulo by zero (x/0, x%0).
  • OverflowError
    Numerical operation exceeds the limits of the platform (rare in Python, but can occur in some math libraries).
  • FloatingPointError
    Raised for floating point issues if explicitly enabled via numpy.seterr. Rare in standard Python.

Lookup Errors

  • LookupError
    Base class for indexing and key errors.
  • IndexError
    Raised when accessing a list/tuple/string index out of range.
  • KeyError
    Raised when accessing a dictionary with a missing key.

Import Errors

  • ImportError
    Raised when import fails.
  • ModuleNotFoundError
    Subclass of ImportError, raised when a module cannot be located.

Attribute and Name Errors

  • AttributeError
    Accessing an undefined attribute (obj.no_such_attr).
  • NameError
    Referring to a variable that is not defined.
  • UnboundLocalError
    Subclass of NameError, raised when referencing a local variable before assignment.

Type and Value Errors

  • TypeError
    Wrong type passed to a function (len(5) or "a" + 1).
  • ValueError
    Argument is the correct type but invalid value (int("abc")).

File and I/O Errors

  • OSError
    Base class for operating system-related errors.
  • FileNotFoundError
    Raised when opening a non-existent file.
  • PermissionError
    Lack of permission to perform an operation.
  • IsADirectoryError
    Raised when a file operation is requested on a directory.
  • NotADirectoryError
    Raised when a directory operation is requested on a non-directory.
  • BlockingIOError, TimeoutError, InterruptedError
    More specific OS-level I/O errors.

Assertion and Runtime

  • AssertionError
    Raised when an assert statement fails.
  • RuntimeError
    Generic error raised when no more specific category applies.
  • NotImplementedError
    Subclass of RuntimeError. Raised when an abstract method is not implemented.
  • RecursionError
    Raised when maximum recursion depth is exceeded.

Other Common Ones

  • EOFError
    Raised when input() hits end-of-file (no input available).
  • StopIteration
    Raised by iterators to signal completion.
  • StopAsyncIteration
    Async version of StopIteration.
  • MemoryError
    Raised when an operation runs out of memory.
  • BufferError
    Related to buffer interface operations.
  • ReferenceError
    Raised when accessing an object through a weak reference that no longer exists.

Best practice: Catch specific exceptions first, then optionally fall back to Exception for safety nets.

 

Summary

Exception handling is a core technique that allows programs to deal with the unexpected. By using constructs like try, except (Python) or try, catch (Java), and always finally, developers can write software that is reliable and user-friendly, even under failure conditions. Robust programs are those that anticipate errors and respond intelligently—not just hope that things never go wrong.