what we blog

Ruby tricks: in need of rescue

Throwing exceptions is nice, but handling them can get a bit of a chore. One of the main reasons: constant reindenting of your code because you insert or remove a begin end section. While your text editor should be able to cope with that just fine, reindenting is just a mess in source control. But, for trivial cases, we can call Ruby to the rescue!

A not very well known feature of the Ruby language is the fact that rescue and ensure at the end of methods does not require a begin. Used properly, this can make your code almost begin-free:

def get(id)
  get!(id)
rescue NotFoundError
  nil
ensure
  # whatever you need to ensure
else
  # whatever you want to happen if no exception was thrown
end

This works like the normal rescue clause. It also gives good reason to factor out code that could raise exceptions you want to handle into its own methods. So, instead of:

def my_long_method(get_additional_docs)
  if get_additional_docs
    begin
      self.additional_docs = fetch_additional_docs
    rescue NotFoundError
      raise "Failed to retrieve additional docs"
    end
  end
end

Do the following:

def my_long_method(get_additional_docs)
  if get_additional_docs
    retrieve_additional_docs
  end
end

def retrieve_additional_docs
  self.additional_docs = fetch_additional_docs
rescue NotFoundError
  raise "Failed to retrieve additional docs"
end