Errors in Crystal
Our first example demonstrates error handling in Crystal. Crystal uses exceptions for error handling, which is different from the explicit return value approach used in some other languages.
# In Crystal, we use exceptions for error handling.
# We'll define a custom exception class for our specific error.
class CannotWorkWithFortyTwoError < Exception
end
# We define a method that may raise an exception
def f(arg : Int32) : Int32
if arg == 42
# Instead of returning an error, we raise an exception
raise CannotWorkWithFortyTwoError.new("can't work with 42")
end
# If no exception is raised, we simply return the result
arg + 3
end
# We can define custom error classes for specific scenarios
class OutOfTeaError < Exception
end
class PowerError < Exception
end
def make_tea(arg : Int32)
case arg
when 2
raise OutOfTeaError.new("no more tea available")
when 4
# In Crystal, we don't need to wrap errors. We can just raise a new exception.
raise PowerError.new("can't boil water")
end
end
# Main execution
begin
[7, 42].each do |i|
begin
result = f(i)
puts "f worked: #{result}"
rescue ex : CannotWorkWithFortyTwoError
puts "f failed: #{ex.message}"
end
end
5.times do |i|
begin
make_tea(i)
puts "Tea is ready!"
rescue ex : OutOfTeaError
puts "We should buy new tea!"
rescue ex : PowerError
puts "Now it is dark."
rescue ex
puts "unknown error: #{ex.message}"
end
end
rescue ex
puts "An unexpected error occurred: #{ex.message}"
end
To run the program, save it as errors.cr
and use the Crystal compiler:
$ crystal errors.cr
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 Crystal, we use exceptions for error handling. Instead of returning error values, we raise exceptions when an error occurs. We can define custom exception classes for specific error scenarios.
The begin
/rescue
blocks in Crystal are similar to try
/catch
blocks in other languages. They allow us to handle different types of exceptions separately.
Crystal doesn’t have a direct equivalent to Go’s error wrapping and errors.Is
functionality. Instead, you can create custom exception hierarchies if you need to check for specific error types.
This example demonstrates basic error handling in Crystal, including raising and catching custom exceptions, which is the idiomatic way to handle errors in this language.