0

I am trying to create my own StandardError exception, but I cannot seem to fire rescue_from with the raise. The error is raised but never rescued. I built a simple application to try it, as follows:

class ApplicationController < ActionController::Base

  protect_from_forgery with: :exception

  class ApplicationController::LocationInvalid < StandardError
  end

  rescue_from ApplicationController::LocationInvalid, with: :reset_it

  raise ApplicationController::LocationInvalid

  private

  def reset_it(exception)
    session.clear
    cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
    puts 'Reset it processed'
  end
end

When I wrap the raise in begin/rescue/end, it prints e as ApplicationController::LocationInvalid:

  begin
    raise ApplicationController::LocationInvalid
  rescue => e
    puts e
  end

Output:

Started GET "/" for 127.0.0.1 at 2015-08-21 15:19:32 -0400 ApplicationController::LocationInvalid

I've tried various forms of specifying the ApplicationController class and not with no change in the results...

Richard_G
  • 4,700
  • 3
  • 42
  • 78
  • Try `raise ApplicationController::LocationInvalid.new`. – CWitty Aug 21 '15 at 19:43
  • @CWitty Thanks for the suggestion. Seemed quite plausible. However, the results were basically the same. I saw a note that "you can raise anything" and it seems you can raise a class or an instance. Rescue_from doesn't seem to share that casual attitude... – Richard_G Aug 21 '15 at 20:32
  • I wonder if you are raising the exception at the time the class is being evaluated, and the def for `reset_it` has not been evaluated yet? Try putting the `raise` in a method, and then invoke that method from the console or something. – Daiku Aug 21 '15 at 20:44
  • 1
    Like Daiku said. Puting it in a method will cause rescue_from to handle it. If you wrap the exception in a begin rescue, then rescue_from won't fire because it's already being rescued. – Daniel Logan Aug 21 '15 at 20:45
  • @DanielLogan It appears you were right regarding placing it in a method but for the reason provided by edariedl. I appreciate everyone's response and assistance. Thanks. – Richard_G Aug 21 '15 at 21:46

1 Answers1

1

According to source code of Rails https://github.com/rails/rails/blob/f62fb985b6a7b90872148f0786219c9cc94c9356/actionpack/lib/action_controller/metal/rescue.rb#L32

rescue_with works only during process_action call but you are raising exception during class evaluation. Probably the easiest way how to test it is to create simple controller with some action and try to raise exception during that action and rescue_with should work.

edariedl
  • 3,234
  • 16
  • 19
  • Very nice. I used after_action to execute a method that threw the error and rescue_from fired. That helps me understand other questions I had, such as why is request available only in a method. Seems to be the same reason. Thanks... – Richard_G Aug 21 '15 at 21:45