try...catch in Ruby

Nurudeen Ibrahim Jan 19, 2022
  1. Rescue With a Generic Error Message in Ruby
  2. Rescue With the Message From the Exception in Ruby
  3. Rescue a Specific Type of Exception in Ruby
try...catch in Ruby

An exception is an undesirable event that occurs during the execution of a program. An example is a ZeroDivisionError when a program tries to divide a number by zero. Rescuing an exception is a way of gracefully handling it so it doesn’t crash the program.

An exception in Ruby is usually made up of two clauses, begin and rescue. The begin clause is equivalent to try in Python or any other similar programming language, while the rescue is equivalent to catch. Below is the syntax.

begin
  # do something that might cause an exception
rescue StandardError
  # handle the exception here
end

Let’s write a simple program that calculates the profit percentage if given the selling and cost prices of the good.

Example Codes:

def profit_percentage(selling_price, cost_price)
  profit = selling_price - cost_price
  "#{profit.fdiv(cost_price) * 100}%"
end

puts profit_percentage(30, 20)
puts profit_percentage(30, nil)

Output:

50.0%
nil can't be coerced into Integer (TypeError)

As we can see in the output above, the second invocation of profit_percentage raised an error because we passed nil as the cost_price. Now let’s illustrate different ways we could have rescued this exception.

Rescue With a Generic Error Message in Ruby

Rescuing with a generic error message is not always helpful because it does not reveal the root cause of the exception.

Example Codes:

def profit_percentage(selling_price, cost_price)
  profit = selling_price - cost_price
  "#{profit.fdiv(cost_price) * 100}%"
rescue StandardError
  'An unknown error occurred.'
end

puts profit_percentage(30, nil)

Output:

An unknown error occurred.

Rescue With the Message From the Exception in Ruby

This method comes in handy if you are not interested in the type of exception raised but only the error message.

Example Codes:

def profit_percentage(selling_price, cost_price)
  profit = selling_price - cost_price
  "#{profit.fdiv(cost_price) * 100}%"
rescue StandardError => e
  e
end

puts profit_percentage(30, nil)

Output:

nil can't be coerced into Integer

Rescue a Specific Type of Exception in Ruby

It is helpful if you are interested in handling only a particular type of exception.

Example Codes:

def profit_percentage(selling_price, cost_price)
  profit = selling_price - cost_price
  "#{profit.fdiv(cost_price) * 100}%"
rescue TypeError
  'An argument of invalid type was detected'
end

puts profit_percentage(30, nil)

Output:

An argument of invalid type was detected

Also, it’s worth mentioning that there’s another optional clause called ensure, which could be helpful in cases where you always need to execute some code regardless of whether an exception was raised or not.

Example Codes:

def profit_percentage(selling_price, cost_price)
  profit = selling_price - cost_price
  puts "#{profit.fdiv(cost_price) * 100}%"
rescue StandardError => e
  puts e
ensure
  puts 'Done calculating profit %'
end

profit_percentage(30, 20)
profit_percentage(30, nil)

Output:

50.0%
Done calculating profit %

nil can't be coerced into Integer
Done calculating profit %

As shown in the output above, the code in the ensure clause got triggered in both invocations of profit_percentage. This clause is usually used when there’s a need to close a file after doing some file operations, regardless of whether an exception occurred or not.

Related Article - Ruby Exception