Syntax of Ruby-Exceptions

Viewed 106

I'm trying to understand the syntax of Ruby-exceptions.

I found this example:

begin
    puts "Running with b=#{ b }"
    exception_if(b)
    puts "After possible exception"
  rescue ArgumentError => e
    puts "An error occured: #{ e }!"
  ensure
    puts "Always excuted, no matter what."
  end

Source: Wiki-Books

"ArgumentError" is the expection-type, which the rescue-branch shall catch? "e" is the reference-variable?

I'm I right there?

Then I found this snippet and that confused me then completely:

begin
  @product = Product.find(params[:id])
rescue => e
  redirect_to root_path
end

Where's the first part before the arrow (=>)?

Can someone explain me, how the two snippets are meant?

2 Answers

Edit: The second snippet is rescuing errors that are instances of StandardError, in a console:

begin
  raise NoMethodError
rescue => e
  puts e.inspect
end
#<NoMethodError: NoMethodError>

The exception object is assigned to the e variable. This can also read

rescue StandardError => e

The first snippet is initially rescue-ing one specific error, if another type of error is raised the ensure block will always be executed and then the method is exited.

As a general rule of thumb, you should only capture exceptions your program can recover from. If the program experiences an unknown exception crash it and fix the issue.

Your interpretation of the first snippet is essentially correct. It's not 100% clear to me what you mean by "reference variable", though.

The identifier after the => arrow will be bound to the exception that was rescued, and is in scope within the rescue block.

The second snippet essentially just leaves out the exception class being rescued, which means it is using the default. If you don't specify the exception class, it will use StandardError as the default, and rescue from all exceptions that are instances of StandardError.

Note: this will not rescue all errors! It will only rescue exceptions that are instances of StandardError, but not all instances of Exception.

For example, SystemStackError directly inherits from Exception and is not a subclass of StandardError, and thus will not be rescued by your second snippet.

In general, exceptions that don't inherit from StandardError are ones that you cannot recover from anyway, such as running out of memory, or corruption of the internal data structures of the VM. You should strive to always specify the exceptions as narrowly as possible and only rescue exceptions that you actually can handle – ideally, you would create custom exception classes for your own code, and only rescue those.

Related