With Rails4.2 I'm not able to handle Exceptions like RoutingError

132 views Asked by At

My application_controller.rb code is:

class ApplicationController < ActionController::Base# Prevent CSRF attacks by raising an exception.#For APIs, you may want to use: null_session instead.
  protect_from_forgery
  before_filter: set_current_user
  rescue_from ActionController::RoutingError, with: : render_error

  def render_error
    p "**************************************"
  end

  def set_current_user
    User.current_user = current_user
  end

 end

Now if I try to hit my home/xyz this exception should have captured but control is never coming to render_error method. Is there anything else which I have to do in order to capture this exception? or if there is any better way available for Rails 4.2 can someone guide me on those I have tried Exception Notificaiton Gem but that too not working it seems. Note : I'm using development environment.

My Error logs :

Started GET "/qweq"
for 172.24.106.197 at 2016 - 09 - 07 16: 03: 01 + 0530

ActionController::RoutingError(No route matches[GET]
    "/qweq"):
  actionpack(4.2.6) lib / action_dispatch / middleware / debug_exceptions.rb: 21: in `call'
  actionpack (4.2.6) lib/action_dispatch/middleware/show_exceptions.rb:30:in `
call '
  railties (4.2.6) lib/rails/rack/logger.rb:38:in `call_app'
railties(4.2.6) lib / rails / rack / logger.rb: 20: in `block in call'
  activesupport (4.2.6) lib/active_support/tagged_logging.rb:68:in `
block in tagged '
  activesupport (4.2.6) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport(4.2.6) lib / active_support / tagged_logging.rb: 68: in `tagged'
  railties (4.2.6) lib/rails/rack/logger.rb:20:in `
call '
  actionpack (4.2.6) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack(1.6.4) lib / rack / methodoverride.rb: 22: in `call'
  rack (1.6.4) lib/rack/runtime.rb:18:in `
call '
  activesupport (4.2.6) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
rack(1.6.4) lib / rack / lock.rb: 17: in `call'
  actionpack (4.2.6) lib/action_dispatch/middleware/static.rb:120:in `
call '
  rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
railties(4.2.6) lib / rails / engine.rb: 518: in `call'
  railties (4.2.6) lib/rails/application.rb:165:in `
call '
  rack (1.6.4) lib/rack/lock.rb:17:in `call'
rack(1.6.4) lib / rack / content_length.rb: 15: in `call'
  rack (1.6.4) lib/rack/handler/webrick.rb:88:in `
service '
  /home/883562/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service' / home / 883562 / .rvm / rubies / ruby - 2.1.4 / lib / ruby / 2.1.0 / webrick / httpserver.rb: 94: in `run'
  /home/883562/.rvm/rubies/ruby-2.1.4/lib/ruby/2.1.0/webrick/server.rb:295:in `
block in start_thread '
2

There are 2 answers

1
Tony Vincent On

config/application.rb

module NameOfYourApp
  class Application < Rails::Application
    require Rails.root.join("lib/custom_public_exceptions")
    config.exceptions_app = CustomPublicExceptions.new(Rails.public_path)
  end
end

config/routes.rb

match "/404" => "errors#error404", via: [ :get, :post, :patch, :delete ]

lib/custom_public_exceptions.rb

class CustomPublicExceptions < ActionDispatch::PublicExceptions
  def call(env)
    status = env["PATH_INFO"][1..-1]

    if status == "404"
      Rails.application.routes.call(env)
    else
      super
    end
  end
end

app/controllers/errors_controller.rb

class ErrorsController < ApplicationController
  def error404
    render status: :not_found
  end
end

app/views/errors/error404.er

  <span> 404 </span>
  <p>Page Not Found<p>

You can make use of the ErrorsController for handling different errors and customizing corresponding view templates to provide better looking error pages

0
Sergio Tulentsev On

The reason why you can't handle routing errors with that code is because route is resolved before any controller is instantiated. If it is not resolved (matching controller/action is not found), then router itself raises this error. Naturally, application controller never sees it.

What you can do is define a "catch-all" route which will map to a controller/action and do your tracking in that action (or whatever it is you wanted to do).