errors/custom_exceptions.rb
tests/_examples/errors/custom_exceptions.rb in the metorex repository.
# Custom Exception Classes Example
# Demonstrates how to create and use custom exception types
# Example 1: Define custom exception classes
class DatabaseError < StandardError
end
class ConnectionError < DatabaseError
end
class QueryError < DatabaseError
end
class ValidationError < StandardError
end
# Example 2: Raising and catching custom exceptions
puts "Example 1: Custom exception types"
begin
raise DatabaseError.new("Database connection failed")
rescue DatabaseError => e
puts "Caught DatabaseError: #{e.message}"
end
begin
raise ConnectionError.new("Could not connect to database")
rescue ConnectionError => e
puts "Caught ConnectionError: #{e.message}"
end
begin
raise QueryError.new("Invalid SQL query")
rescue QueryError => e
puts "Caught QueryError: #{e.message}"
end
# Example 3: Catching parent exception class
puts ""
puts "Example 2: Catching via parent class"
begin
raise ConnectionError.new("Connection timeout")
rescue DatabaseError => e
puts "Caught as DatabaseError: #{e.message}"
end
begin
raise QueryError.new("Table not found")
rescue DatabaseError => e
puts "Caught as DatabaseError: #{e.message}"
end
# Example 4: Multiple rescue clauses with custom exceptions
puts ""
puts "Example 3: Multiple rescue clauses"
def process_database_operation(operation_type)
begin
if operation_type == "connect"
raise ConnectionError.new("Connection failed")
elsif operation_type == "query"
raise QueryError.new("Query syntax error")
elsif operation_type == "validate"
raise ValidationError.new("Invalid input data")
end
rescue ConnectionError => e
puts "Connection issue: #{e.message}"
rescue QueryError => e
puts "Query issue: #{e.message}"
rescue ValidationError => e
puts "Validation issue: #{e.message}"
rescue DatabaseError => e
puts "General database issue: #{e.message}"
rescue StandardError => e
puts "General error: #{e.message}"
end
end
process_database_operation("connect")
process_database_operation("query")
process_database_operation("validate")
# Example 5: Re-raising custom exceptions
puts ""
puts "Example 4: Re-raising exceptions"
def attempt_operation
begin
raise QueryError.new("Failed to execute query")
rescue QueryError => e
puts "Caught in attempt_operation: #{e.message}"
raise
end
end
begin
attempt_operation()
rescue QueryError => e
puts "Caught in outer scope: #{e.message}"
end
# Example 6: Custom exception hierarchy usage
puts ""
puts "Example 5: Exception hierarchy in action"
def handle_database_work
begin
raise ConnectionError.new("Database unreachable")
rescue ConnectionError => e
puts "Specific handler: #{e.message}"
rescue DatabaseError => e
puts "General handler: #{e.message}"
end
end
handle_database_work()
Output:
Example 1: Custom exception types
Caught DatabaseError: Database connection failed
Caught ConnectionError: Could not connect to database
Caught QueryError: Invalid SQL query
Example 2: Catching via parent class
Caught as DatabaseError: Connection timeout
Caught as DatabaseError: Table not found
Example 3: Multiple rescue clauses
Connection issue: Connection failed
Query issue: Query syntax error
Validation issue: Invalid input data
Example 4: Re-raising exceptions
Caught in attempt_operation: Failed to execute query
Caught in outer scope: Failed to execute query
Example 5: Exception hierarchy in action
Specific handler: Database unreachable