Errors in Ruby
In Ruby, it’s idiomatic to communicate errors via exceptions, which is different from the explicit error return values used in some other languages. Ruby’s approach makes it easy to handle errors using language constructs like begin, rescue, and ensure.
# In Ruby, we don't need to explicitly import modules for basic functionality
# We define a method that may raise an exception
def f(arg)
if arg == 42
# Instead of returning an error, we raise an exception
raise ArgumentError, "can't work with 42"
end
# If no exception is raised, we simply return the result
arg + 3
end
# We can define custom exception classes
class OutOfTeaError < StandardError; end
class PowerError < StandardError; end
def make_tea(arg)
case arg
when 2
raise OutOfTeaError, "no more tea available"
when 4
# We can raise an exception with a nested cause
raise PowerError, "making tea: can't boil water"
end
# If no exception is raised, the method implicitly returns nil
end
# Main execution
[7, 42].each do |i|
# It's common to use a begin/rescue block for error handling
begin
result = f(i)
puts "f worked: #{result}"
rescue ArgumentError => e
puts "f failed: #{e.message}"
end
end
5.times do |i|
begin
make_tea(i)
puts "Tea is ready!"
rescue OutOfTeaError
puts "We should buy new tea!"
rescue PowerError
puts "Now it is dark."
rescue StandardError => e
puts "unknown error: #{e.message}"
end
endWhen you run this Ruby script, you’ll get output similar to this:
f worked: 10
f failed: can't work with 42
Tea is ready!
Tea is ready!
We should buy new tea!
Tea is ready!
Now it is dark.In Ruby, we use exceptions for error handling. The raise keyword is used to throw an exception, and rescue is used to catch and handle exceptions. This is similar to try/catch in many other languages.
Ruby doesn’t have a built-in way to wrap errors like Go’s fmt.Errorf with %w, but you can achieve similar functionality by setting the cause of an exception when you raise it, or by using custom exception classes that contain additional context.
The StandardError class is the default superclass for all standard errors. You can create custom error classes by inheriting from StandardError or any of its subclasses.
Ruby’s case statement is used here as an equivalent to Go’s if/else if chain in the makeTea function.
Remember that in Ruby, the last evaluated expression in a method is implicitly returned, so we don’t need explicit return statements in many cases.
This example demonstrates how Ruby’s exception handling mechanism can be used to achieve similar error handling patterns as in Go, while following Ruby’s idiomatic practices.