Exception handling is a crucial aspect of robust software development. In Object Pascal, exceptions provide a way to handle errors and other exceptional conditions in a controlled manner. This section will cover the basics of exception handling, how to use exceptions in object-oriented programming (OOP), and best practices for creating and managing exceptions in Delphi.
Key Concepts
- Exceptions: Special conditions that alter the normal flow of execution.
- Try...Except Block: A construct to handle exceptions.
- Try...Finally Block: Ensures that certain code runs regardless of whether an exception occurs.
- Raising Exceptions: Creating and throwing exceptions.
- Custom Exceptions: Defining your own exception classes.
Try...Except Block
The try...except block is used to handle exceptions. It allows you to catch and respond to exceptions that occur within the try block.
Syntax
try
// Code that might raise an exception
except
on E: ExceptionType do
// Handle the exception
end;Example
procedure DivideNumbers(A, B: Integer);
begin
try
WriteLn('Result: ', A div B);
except
on E: EDivByZero do
WriteLn('Error: Division by zero is not allowed.');
end;
end;
begin
DivideNumbers(10, 0);
end.In this example, if B is zero, an EDivByZero exception is raised, and the message "Error: Division by zero is not allowed." is displayed.
Try...Finally Block
The try...finally block ensures that the code in the finally section is executed regardless of whether an exception occurs.
Syntax
Example
procedure OpenFile;
var
FileHandle: TextFile;
begin
AssignFile(FileHandle, 'example.txt');
try
Reset(FileHandle);
// Perform file operations
finally
CloseFile(FileHandle);
end;
end;In this example, the file is guaranteed to be closed whether an exception occurs during file operations or not.
Raising Exceptions
You can raise exceptions using the raise keyword. This is useful for signaling error conditions explicitly.
Syntax
Example
procedure CheckAge(Age: Integer);
begin
if Age < 18 then
raise Exception.Create('Age must be 18 or older.');
end;
begin
try
CheckAge(16);
except
on E: Exception do
WriteLn('Exception: ', E.Message);
end;
end.In this example, an exception is raised if the age is less than 18, and the message "Exception: Age must be 18 or older." is displayed.
Custom Exceptions
Creating custom exception classes allows you to handle specific error conditions more precisely.
Syntax
Example
type
EInvalidInput = class(Exception)
end;
procedure ValidateInput(Input: Integer);
begin
if Input < 0 then
raise EInvalidInput.Create('Input must be non-negative.');
end;
begin
try
ValidateInput(-1);
except
on E: EInvalidInput do
WriteLn('Invalid input: ', E.Message);
end;
end.In this example, a custom exception EInvalidInput is defined and used to signal invalid input conditions.
Best Practices
- Use Specific Exceptions: Catch specific exceptions rather than the generic
Exceptionclass to handle different error conditions appropriately. - Clean Up Resources: Always release resources (e.g., files, memory) in a
finallyblock to avoid resource leaks. - Provide Meaningful Messages: Include clear and informative messages when raising exceptions to aid in debugging.
- Avoid Overusing Exceptions: Use exceptions for exceptional conditions, not for regular control flow.
Practical Exercise
Exercise
Create a Delphi application that reads an integer from the user and checks if it is a prime number. If the input is not a valid integer, raise a custom exception. If the number is not prime, raise another custom exception.
Solution
type
EInvalidNumber = class(Exception)
end;
ENotPrime = class(Exception)
end;
function IsPrime(Number: Integer): Boolean;
var
I: Integer;
begin
if Number <= 1 then
Exit(False);
for I := 2 to Trunc(Sqrt(Number)) do
if Number mod I = 0 then
Exit(False);
Result := True;
end;
procedure CheckPrime(Input: string);
var
Number: Integer;
begin
if not TryStrToInt(Input, Number) then
raise EInvalidNumber.Create('Input is not a valid integer.');
if not IsPrime(Number) then
raise ENotPrime.Create('The number is not prime.');
end;
begin
try
CheckPrime('15');
except
on E: EInvalidNumber do
WriteLn('Error: ', E.Message);
on E: ENotPrime do
WriteLn('Error: ', E.Message);
end;
end.In this solution, two custom exceptions EInvalidNumber and ENotPrime are defined. The CheckPrime procedure checks if the input is a valid integer and if it is a prime number, raising appropriate exceptions for invalid input and non-prime numbers.
Conclusion
Exception handling is a powerful feature in Delphi/Object Pascal that helps you manage errors and exceptional conditions gracefully. By using try...except and try...finally blocks, raising exceptions, and creating custom exceptions, you can write more robust and maintainable code. Remember to follow best practices to ensure your exception handling is effective and efficient.
Delphi/Object Pascal Programming Course
Module 1: Introduction to Delphi/Object Pascal
- Introduction to Delphi and Object Pascal
- Setting Up the Development Environment
- First Delphi Application
- Basic Syntax and Structure
- Variables and Data Types
Module 2: Control Structures and Procedures
- Conditional Statements
- Loops and Iteration
- Procedures and Functions
- Scope and Lifetime of Variables
- Error Handling and Debugging
Module 3: Working with Data
Module 4: Object-Oriented Programming
- Introduction to OOP
- Classes and Objects
- Inheritance and Polymorphism
- Interfaces and Abstract Classes
- Exception Handling in OOP
Module 5: Advanced Delphi Features
- Generics and Collections
- Multithreading and Parallel Programming
- Component-Based Development
- Delphi Runtime Library (RTL)
- Advanced Debugging Techniques
Module 6: GUI Development with VCL and FMX
- Introduction to VCL
- Creating Forms and Controls
- Event-Driven Programming
- Introduction to FireMonkey (FMX)
- Cross-Platform Development with FMX
Module 7: Web and Mobile Development
- Web Development with Delphi
- RESTful Services
- Mobile Development with Delphi
- Deploying Mobile Applications
- Integrating with Web Services
Module 8: Best Practices and Design Patterns
- Code Organization and Documentation
- Design Patterns in Delphi
- Refactoring Techniques
- Unit Testing and Test-Driven Development
- Performance Optimization
