使用Rails4.2,我无法处理像RoutingError这样的异常

时间:2016-09-07 11:03:43

标签: ruby-on-rails exception-handling rails-4-2-1

我的application_controller.rb代码是:

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

现在,如果我尝试点击home/xyz此异常应该已经捕获,但控制永远不会进入render_error方法。 为了捕获这个异常,还有什么我需要做的吗?或者如果有更好的方法可用于Rails 4.2,有人可以指导我那些我尝试过Exception Notificaiton宝石的人,但这似乎也没有用。 注意:我使用的是开发环境。

我的错误记录:

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 个答案:

答案 0 :(得分:3)

您无法使用该代码处理路由错误的原因是因为路径在实例化任何控制器之前已解决。如果未解决(找不到匹配的控制器/操作),则路由器本身会引发此错误。当然,应用程序控制器永远不会看到它。

您可以做的是定义一个“全能”路线,该路线将映射到控制器/动作并在该动作中进行跟踪(或者您想要做的任何事情)。

答案 1 :(得分:0)

配置/ 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

配置/ 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

应用程序/控制器/ errors_controller.rb

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

应用程序/视图/错误/ error404.er

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

您可以使用ErrorsController来处理不同的错误并自定义相应的视图模板,以提供更好看的错误页面