5

I have a number of controllers in my Ruby on Rails apps with a rescue handler at the end of the action that basically catches any unhandled errors and returns some kind of "user friendly" error. However, when I'm doing rake test I'd like to have those default rescue handlers disabled so I can see the full error & stack trace. Is there any automated way to do this?

Update to clarify: I have an action like this:

def foo
  # do some stuff...
rescue
  render :text => "Exception: #{$!}" # this could be any kind of custom render
end

Now when I functional test this, if the exception is raised then I'm going to get just a little bit of info about the exception, but what I'd like is for it to act as though there's no rescue handler there, so I get the full debug information.

Update: SOLUTION

I did this:

  rescue:
    raise unless Rails.env.production?
    render :text => "Exception: #{$!}" # this could be any kind of custom render
  end
Simon Woodside
  • 7,175
  • 5
  • 50
  • 66

5 Answers5

10

Not quite automated, but how modifying your code to re-throw exceptions whenever called within a test?

Perhaps something like this:

def foo
  # do some stuff...
rescue
  raise if ENV["RAILS_ENV"] == "test"
  render :text => "Exception: #{$!}" # this could be any kind of custom render
end
nioq
  • 3,215
  • 1
  • 23
  • 18
  • 3
    raise if Rails.env.test? is cleaner IMO – Scott Jan 11 '10 at 14:37
  • @Steven this doesn't really rescue only in production. It raises where it is.. but if you have 20 lines of code in the #do stuff then the raise gives no reference to this. The trace indicates the error occurred on the line that the raise is on. – baash05 Feb 10 '13 at 23:25
  • 1
    Actually, no. raise *with no arguments* re-raises the exception we just caught, keeping the stack trace intact. In other words, it would correctly indicate where the exception was originally raised and not the line `raise if Rails.env.test?` – nioq Feb 12 '13 at 11:35
0

I think the easiest thing to do is verify that the correct render was called-- or whatever was different from the regular, non-exceptional case.

ndp
  • 21,546
  • 5
  • 36
  • 52
0

Have you looked at using the assert_raise( exception1, exception2, ... ) { block } call and then printing the exception from the block?

Scott
  • 654
  • 5
  • 10
0

Which method are you using? There are two rescue methods in ActionController.

I have this in my base controller:

def rescue_action_in_public(exception)
    response_code = response_code_for_rescue(exception)
    status = interpret_status(response_code)
    respond_to do |format|
        format.html { render_optional_error_file response_code}
        format.js { render :update, :status => status  do |page| page.redirect_to(:url => error_page_url(status)) end}
end

end

This only displays custom errors in production mode.

Kyle Boon
  • 5,213
  • 6
  • 39
  • 50
-1

You shouldn't need to disable your rescue block. Use the assert_raise method (as suggested by Scott), and in the block, call the method that you expect an exception from.

For example:

def test_throws_exception
  assert_raise Exception do
    raise_if_true(true)
  end
end
Lucas Wilson-Richter
  • 2,274
  • 1
  • 18
  • 24
  • I'm not trying to assert an exception, I know all about how do do that and have done it many times. I'm trying to get full information about exceptions that occur when I don't expect them (including stack trace) but only when I'm in test mode. – Simon Woodside May 13 '09 at 23:26
  • Ah. Sorry. I misunderstood what you were trying to achieve. – Lucas Wilson-Richter May 14 '09 at 00:01