Rescue from dispatching 4

Posted by pratik
on Sunday, July 20

This question gets asked quite a few times, if there’s an easy way to handle exceptions raised while dispatching a request (routing exceptions, invalid method etc.) gracefully and show a customized error page. After this commit, there is.

rescue_from to the rescue

Now you can handle those exceptions inside your application.rb like :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ApplicationController < ActionController::Base
  rescue_from ActionController::RoutingError, :with => :route_not_found
  rescue_from ActionController::MethodNotAllowed, :with => :invalid_method
  
  private
  
  def route_not_found
    render :text => 'What the fuck are you looking for ?', :status => :not_found
  end
  
  def invalid_method
    message = "Now, did your mom tell you to #{request.request_method.to_s.upcase} that ?"
    render :text => message, :status => :method_not_allowed
  end
end

Just make sure you don’t raise another exception from your rescue_from action!

Dispatcher callbacks 1

Posted by pratik
on Tuesday, October 16

Changeset 7640 introduced 2 new members to rails family of callbacks : before_dispatch and after_dispatch. These callbacks are executed before/after every request, and provides you with hooks at much higher level than normal before_filter and after_filter of ActionController::Base.

Also, note that after_filter are not executed if your action raises an exception. So dispatcher callbacks might be a better fit for performance related logging, etc. where the final outcome of your controller doesn’t really matter, and you want your callbacks to be executed for each and every request.

For example, try the following in your environment.rb :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'dispatcher'
module ActionController
  class Dispatcher
    def start_timer
      @start_time = Time.now
    end
    
    def end_timer
      RAILS_DEFAULT_LOGGER.info "="*100
      RAILS_DEFAULT_LOGGER.info "      URL : #{@request.url}"
      RAILS_DEFAULT_LOGGER.info "     Real : #{Time.now-@start_time} seconds"
      RAILS_DEFAULT_LOGGER.info "Less Real : #{@response.headers["X-Runtime"]} seconds"
      RAILS_DEFAULT_LOGGER.info "="*100
    end
    
    before_dispatch :start_timer
    after_dispatch :end_timer
  end
end