Skip to content
Ruby

Error Handling

Raise and rescue typed exceptions with ensure and retry.

#error#exception#rescue

Code

ruby
class ValidationError < StandardError
  attr_reader :field
  def initialize(field, msg)
    @field = field
    super(msg)
  end
end

def validate_age(age)
  raise ValidationError.new(:age, "must be >= 0") if age < 0
  raise ValidationError.new(:age, "must be <= 130") if age > 130
  "ok"
end

# begin/rescue/ensure
def process(age)
  begin
    result = validate_age(age)
    puts "result: #{result}"
  rescue ValidationError => e
    puts "Validation failed on #{e.field}: #{e.message}"
  rescue => e
    puts "Unexpected: #{e.class}"
  ensure
    puts "cleanup"
  end
end

process(25)
process(-1)
process(200)

# Retry on transient failure
attempts = 0
begin
  attempts += 1
  raise "boom" if attempts < 3
  puts "succeeded on attempt #{attempts}"
rescue => e
  puts "attempt #{attempts} failed: #{e.message}"
  retry if attempts < 3
end

# else and ensure
def divide(a, b)
  result = a / b
  puts "computed"
  result
rescue ZeroDivisionError
  :undefined
ensure
  puts "always runs"
end

puts divide(10, 2)
puts divide(1, 0)