Wednesday, May 23, 2012

How do you throw and catch exceptions in ruby?

To throw an exception (or Error) in ruby, you simply have to type something along the lines of raise 'you did something wrong' inside a begin and end block. This raises a RuntimeError. If you would like to raise some other error, such as a LocalJumpError or, for example, some other error object that you defined,  you can instead say raise LocalJumpError 'you jumped around and you shouldn't have!'. You can raise an error without a message as in simply raise MyError, or you can even raise a RuntimeError with no message by just typing raise.


To catch an error (to do something when an error happens), you can say rescue. rescue with no arguments will simply catch any error, rescue RuntimeError will catch only RuntimeErrors, and rescure RuntimeError => e will catch only RuntimeErrors and provide you with a reference to the RuntimeError object which was raised, and which you can call methods on as specified in the ruby documentation. For example, e.message would return the string that was passed along with the raise clause.


The allegory to a finally clause in java or python is the ensure statement in ruby. Anything positioned after this statement but before the end of the begin...end block will always be executed, no matter what. Ruby does NOT operate by the same rules as java and python when it comes to returning things inside the begin...end block, and raises a lot of confusing LocalJumpErrors if you try to.


Here's a full example:


def raise_if_string x
  raise RuntimeError, 'you tried to pass a string, didn't you?' unless x.class != String
end


begin
  raise_if_string 5       #will do nothing
  raise_if_string 'hello'   #will throw RuntimeError
rescue RuntimeError => e
  print e.message
ensure
  puts 'this will always be printed. goodbye'
end


The output of this would be:


you tried to pass a string, didn't you?
this will always be printed. goodbye


So that's how you throw and catch exceptions in ruby.

No comments:

Post a Comment