Welcome to Exception Handling!
Welcome to one of the most important topics in Software Systems Development: Exception Handling. Have you ever been using an app or a game and suddenly it froze or closed unexpectedly with an error screen? That happens when a program runs into an unexpected problem that it doesn't know how to deal with. In this chapter, you will learn how to write robust programs that can handle unexpected problems gracefully without crashing.
Don't worry if programming errors have felt confusing in the past. We will break everything down step-by-step using clear, real-world analogies!
1. What is an Exception?
To understand exception handling, we first need to distinguish between different types of programming errors:
1. Syntax / Compile-Time Errors: Mistakes in the grammar of your code (like a missing semicolon or a misspelled keyword). The compiler catches these before the program even runs.
2. Logic Errors: The code runs without crashing, but produces the wrong result (e.g. using a plus sign instead of a minus sign in a calculation).
3. Run-Time Errors (Exceptions): Errors that occur while the program is running. The code is syntactically correct, but something unexpected happens during execution that prevents the computer from continuing normal operation.
An Exception is an object created (or thrown) by the runtime environment when an error occurs during execution. If the program does not handle this exception, it will crash immediately.
Analogy: Imagine driving a car. A flat tyre is an unexpected event (an exception). If you have a spare tyre and a jack in the boot (an exception handler), you can fix the problem and continue your journey. If you don't, your journey comes to an abrupt halt (the program crashes)!
Key Takeaway
An exception is a run-time error event. Exception handling allows a program to detect this error, respond to it safely, and keep running.
2. The Try-Catch-Finally Structure
In object-oriented programming (such as C# in CCEA SSD), we handle exceptions using a structured block made of try, catch, and optional finally statements.
The 'try' Block
The try block encloses the section of code that might potentially cause an error. Think of this as the "hazard zone". You are telling the computer: "Try to run this code, but keep an eye out for any problems."
The 'catch' Block
The catch block is the "safety net". If an exception occurs inside the try block, execution jumps immediately to the matching catch block. The code inside catch runs to resolve the issue, display a user-friendly message, or log the error.
The 'finally' Block
The finally block is optional. It contains code that always runs, regardless of whether an exception occurred or not. It is typically used for "cleanup" tasks, such as closing file streams or database connections.
Memory Trick: Remember the acronym TCF:
- Try the risky code.
- Catch the mistake.
- Finally clean up.
3. Common Built-in Exception Classes
In C#, all exceptions inherit from the base class System.Exception. Here are the most common exceptions you need to know for your exam:
1. FormatException: Occurs when the format of an argument is invalid. For example, trying to convert the text string "hello" into an integer using int.Parse() or Convert.ToInt32().
2. DivideByZeroException: Occurs when a calculation attempts to divide any integer by zero (\(x / 0\)). In mathematics and computing, division by zero is undefined.
3. IndexOutOfRangeException: Occurs when trying to access an element of an array or collection using an index that is outside its boundaries (e.g. trying to access index \(5\) in an array of length \(3\)).
4. NullReferenceException: Occurs when you try to access a method or property of an object variable that currently points to null (i.e. it hasn't been instantiated with new).
5. OverflowException: Occurs when an arithmetic operation produces a result that is outside the storage range of the data type.
Did You Know?
Floating-point numbers (like double or float) in C# do not throw a DivideByZeroException! Instead, dividing a double by \(0.0\) results in special values like Infinity or NaN (Not a Number). Integer division by \(0\), however, will always throw an exception.
Key Takeaway
Different types of errors throw specific exception objects. Knowing which exception can occur helps you write targeted catch blocks.
4. Using Multiple Catch Blocks
A single try block can have multiple catch blocks attached to it. This allows your program to respond differently depending on the specific error that took place.
Important Rule of Ordering: You must always catch specific exceptions before more general exceptions. The base class Exception will catch everything, so if you put it first, none of the catch blocks below it will ever run!
Example Order of Handling:
1. try block: Prompt user for two numbers and divide them.
2. catch (FormatException ex): Handles non-numeric text input.
3. catch (DivideByZeroException ex): Handles entering \(0\) as the divisor.
4. catch (Exception ex): Catches any other unforeseen errors as a fallback.
Common Mistake to Avoid
Never leave a catch block completely empty (known as "swallowing" an exception). If an error happens and your catch block does nothing, the error remains hidden, making bugs nearly impossible to track down!
5. Throwing Exceptions Manually
Sometimes you want your own code to signal that an invalid state has occurred. You can explicitly trigger an exception using the throw keyword.
For example, if a method accepts an age parameter for a driving licence application, and the user passes \(-5\), you can write:
throw new ArgumentException("Age cannot be negative.");
When an exception is thrown, normal execution halts, and the runtime searches up the call stack for the nearest matching try-catch block to handle it.
6. Summary and Quick Revision Check
Let's review the core concepts of Exception Handling for AS 1:
Robustness: The ability of software to cope with execution errors and continue operating smoothly.
Try: Surrounds code that may fail.
Catch: Intercepts and handles specific exceptions when they arise.
Finally: Guarantees execution of cleanup code, whether an error occurred or not.
Throw: Manually creates and raises an exception when business rules or parameters are violated.
By mastering exception handling, you ensure your software applications are reliable, user-friendly, and professional!