1

If there is an exception in a controller action and rescue is used, Rails does not show the exception either in the browser (which is O.K), nor does it write the exception to the log file.

Is there a way to get Rails to write the exception to the log file in this case?

Example:

def some_action
  2/0
rescue
  #this code is called, but Rails does not write the exception to the log
end

2 Answers 2

4

You're rescuing the exception, so it won't log it because nothing bad actually happened since it was, in fact, "rescued".

You can put the following code within your rescue block to put an entry in the log:

logger.warn "Exception rescued!"

You can read more about using the logger in the Rails Guides.

Sign up to request clarification or add additional context in comments.

5 Comments

That's exactly the problem :) -- I have a rescue in an action, which when executed redirects to the controllers index page. When an exception occurs, in order to found out what the exception is, I have to remove the rescue part and re-run the code. It would be nice if Rails could just log the exception to file!
It's not logging the exception because Rails doesn't know about it because you rescued it before it bubbled up to Rails in the call stack.
Is there some Ruby magic that can do this? I know we can override the raise method, but rescue is a keyword..:(
…you can manually put an entry in the log like I stated in my answer. This will do exactly what you want in one line of code per rescue, unless I'm misunderstanding you.
You're right about that, but that would be code in many places. I'll try hacking around with rescue_from and somehow calling the code I have in the rescue block from there. Let's see..
0

I ended up using rescue_from in the ApplicationController, logging the exception message and backtrace, and then using params[:controller] and params[:action] to determine what controller/action to redirect to.

For example, if PostsController#show exception'ed out, I would redirect to PostsController#index from within rescue_from. It's been working so far, so it doesn't seem to be a bad thing to do redirect_to from within rescue_from. Time will let me know, I'm sure! (Just need to make sure that my redirects don't cause some infinite loops!)

And just in someone is interested in this hack (try at your own risk!):

class ApplicationController < ActionController::Base

  def determine_redirect_to_path(controller,action)
    ...
  end

  rescue_from StandardError do |exception|    
    backtrace_size = exception.backtrace.size
    if backtrace_size >= 2 then max_range = 2
    elsif backtrace_size >= 1 then max_range = 1
    end
    if max_range > 0      
      s = "rescued_from:: #{params[:controller]}##{params[:action]}: #{exception.inspect}\n#{exception.backtrace[0..max_range].to_s}\n"
      logger.error s
    end
    redirect_to determine_redirect_to_path(params[:controller],params[:action])
  end      
end  

2 Comments

Rescuing from all exceptions like this will lead to unexpected behavior for the user as any actions they attempted to make that throw an exception will have silently failed to them.
I've proposed an edit to change it from Exception to StandardError per Andrew's comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.