Ruby Exception List
Understanding Ruby's built-in error types
⚠️ What are Ruby Exceptions?
Ruby exceptions are error objects that signal when something goes wrong in your program. Understanding different exception types helps you handle errors gracefully and write more robust, reliable code that doesn't crash unexpectedly.
# Handling exceptions
begin
result = 10 / 0
rescue ZeroDivisionError => e
puts "Error: #{e.message}"
end
Output:
Error: divided by 0
Exception Categories
Math Errors
Errors from mathematical operations
ZeroDivisionError
FloatDomainError
Name Errors
Errors from undefined names
NameError
NoMethodError
File Errors
Errors from file operations
IOError
EOFError
Type Errors
Errors from type mismatches
TypeError
ArgumentError
🔹 StandardError Exceptions
StandardError is the parent class for most common exceptions. These are the errors you'll typically rescue in your code. They represent recoverable errors that your program can handle gracefully without crashing.
# ArgumentError - wrong number of arguments
def greet(name)
puts "Hello, #{name}"
end
begin
greet()
rescue ArgumentError => e
puts "ArgumentError: #{e.message}"
end
# TypeError - wrong type
begin
result = "5" + 5
rescue TypeError => e
puts "TypeError: #{e.message}"
end
# RuntimeError - generic error
begin
raise "Something went wrong"
rescue RuntimeError => e
puts "RuntimeError: #{e.message}"
end
Output:
ArgumentError: wrong number of arguments (given 0, expected 1) TypeError: String can't be coerced into Integer RuntimeError: Something went wrong
🔹 Math and Number Exceptions
Math exceptions occur during numerical operations. These errors happen when you perform invalid mathematical calculations like dividing by zero or taking the square root of negative numbers in certain contexts.
# ZeroDivisionError
begin
result = 100 / 0
rescue ZeroDivisionError => e
puts "ZeroDivisionError: #{e.message}"
end
# FloatDomainError
begin
result = Math.sqrt(-1)
rescue FloatDomainError => e
puts "FloatDomainError: #{e.message}"
end
# RangeError
begin
("a".."z").to_a[100]
rescue RangeError => e
puts "RangeError: #{e.message}"
end
Output:
ZeroDivisionError: divided by 0 FloatDomainError: Numerical argument is out of domain RangeError: (no error in this case, returns nil)
🔹 Name and Method Exceptions
Name exceptions occur when Ruby can't find a variable, constant, or method. These are common errors when you have typos or try to use something before defining it. They help catch spelling mistakes early.
# NameError - undefined variable or constant
begin
puts undefined_variable
rescue NameError => e
puts "NameError: #{e.message}"
end
# NoMethodError - method doesn't exist
begin
result = "hello".non_existent_method
rescue NoMethodError => e
puts "NoMethodError: #{e.message}"
end
# NoMethodError - nil object
begin
value = nil
result = value.upcase
rescue NoMethodError => e
puts "NoMethodError on nil: #{e.message}"
end
Output:
NameError: undefined local variable or method `undefined_variable' NoMethodError: undefined method `non_existent_method' for "hello":String NoMethodError on nil: undefined method `upcase' for nil:NilClass
🔹 Index and Key Exceptions
Index exceptions happen when accessing array or hash elements incorrectly. While Ruby often returns nil for missing elements, you can raise exceptions explicitly to enforce stricter error handling in your applications.
# IndexError - array index out of bounds
begin
arr = [1, 2, 3]
arr.fetch(10)
rescue IndexError => e
puts "IndexError: #{e.message}"
end
# KeyError - hash key doesn't exist
begin
hash = { name: "Alice" }
hash.fetch(:age)
rescue KeyError => e
puts "KeyError: #{e.message}"
end
# StopIteration - no more elements
begin
enum = [1, 2, 3].each
4.times { puts enum.next }
rescue StopIteration => e
puts "StopIteration: #{e.message}"
end
Output:
IndexError: index 10 outside of array bounds KeyError: key not found: :age 1 2 3 StopIteration: iteration reached an end
🔹 File and IO Exceptions
IO exceptions occur during file operations and input/output tasks. These errors happen when files don't exist, permissions are denied, or you reach the end of a file. Proper handling prevents data loss.
# IOError - general IO error
begin
file = File.open("nonexistent.txt")
rescue Errno::ENOENT => e
puts "File not found: #{e.message}"
end
# EOFError - end of file reached
begin
File.open("test.txt", "w") { |f| f.write("test") }
File.open("test.txt", "r") do |f|
f.read
raise EOFError, "Reached end of file"
end
rescue EOFError => e
puts "EOFError: #{e.message}"
end
# SystemCallError - system-level error
begin
Dir.mkdir("/root/forbidden")
rescue SystemCallError => e
puts "SystemCallError: #{e.message}"
end
Output:
File not found: No such file or directory @ rb_sysopen EOFError: Reached end of file SystemCallError: Permission denied
🔹 Custom Exception Handling
You can create custom exceptions for specific error scenarios in your application. Custom exceptions make your code more maintainable by providing clear, meaningful error messages that describe exactly what went wrong.
# Creating custom exceptions
class InvalidAgeError < StandardError
def initialize(age)
super("Invalid age: #{age}. Age must be between 0 and 120.")
end
end
class InsufficientFundsError < StandardError; end
# Using custom exceptions
def validate_age(age)
raise InvalidAgeError.new(age) if age < 0 || age > 120
puts "Valid age: #{age}"
end
def withdraw(amount, balance)
raise InsufficientFundsError, "Not enough funds" if amount > balance
balance - amount
end
begin
validate_age(150)
rescue InvalidAgeError => e
puts e.message
end
begin
withdraw(100, 50)
rescue InsufficientFundsError => e
puts "Error: #{e.message}"
end
Output:
Invalid age: 150. Age must be between 0 and 120. Error: Not enough funds