exact exceptions in rescue_from

rescue_from stores exception class names in a hash table, and associates them with handlers.

When an exception is raised there's a name lookup, and if an entry is found its handler is invoked. In particular rescue_from does not emulate Ruby's rescue semantics with regard to inheritance.

Which is the rationale? Don't you think taking is_a? and declaration order into account would provide a better (expected) usage? I could write a patch in that case.

-- fxn

PS: A friend of mine and Google Groups didn't receive this email, please excuse me if you get it more than once.

So you can declare handlers before exception classes or for classes which may be unavailable (say, you have Active Record disabled.)

jeremy

Thank you, I don't get it though.

An invocation requires classes as arguments:

  def rescue_from(*klasses, &block)     ...     klasses.each do |klass|       rescue_handlers[klass.name] = options[:with]     end   end

so they have to be defined at the point of the declaration. Taking that into account, why handler_for_rescue does this:

  def handler_for_rescue(exception)     case handler = rescue_handlers[exception.class.name]     when Symbol       method(handler)     when Proc       handler.bind(self)     end   end

instead of this (off the top of my head):

  def handler_for_rescue(exception)     pair = rescue_handlers.select do |pair|       exception.is_a?(pair.exception)     end     return unless pair

    case pair.handler     when Symbol       method(pair.handler)     when Proc       pair.handler.bind(self)     end   end

assuming request_handlers in this alternative is an array of pairs of some sort to preserve declaration order.

-- fxn

> So you can declare handlers before exception classes or for classes > which may be unavailable (say, you have Active Record disabled.)

Thank you, I don't get it though.

An invocation requires classes as arguments:

I think a patch which preserves (grants) the ability to use strings as arguments to rescue_from but fixes the semantics would be good to review.

Here we go!

  http://dev.rubyonrails.org/ticket/10079

The diff has been computed from edge a few minutes ago.

I chose to provide rescue priority from right to left, bottom to top, and up the hierarchy. Since the code that raises exceptions appears usually below the declarations, and I would expect handlers in children to be called before handlers in parents, I thought that could be an intuitive order.

As per strings, since the objective was to be able to declare handlers for exceptions whose definition has not yet been seen, when we loop over the handlers when an exception is raised we do not complain if some string-to-constant fails. Perhaps that's an early exception and we have not yet seen the definition, so a NameError didn't seem consistent with the original aim. Another objective was to be able to declare handlers for classes that won't be loaded at all, we accomplish that as well. Typos won't be apparent unfortunately, but we can't be strict and tolerant at the same time.

Best,

-- fxn

Here we go!

  http://dev.rubyonrails.org/ticket/10079

The diff has been computed from edge a few minutes ago.

Wicked, nice work.