【问题标题】:How to Overwrite ActionController::RoutingError on Rails application to catch "bad Ip"如何在 Rails 应用程序上覆盖 ActionController::RoutingError 以捕获“坏 Ip”
【发布时间】:2016-05-18 10:19:30
【问题描述】:

我每天都有错误的请求,而不是在 production.log 中生成大量日志,如下所示:

F, [2016-02-08T15:39:17.698761 #2437] FATAL -- : 
ActionController::RoutingError (No route matches [GET] "/sites/default/files/elsevier/eop/S0025-7753(12)00231-X.pdf"):
  actionpack (4.0.2) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.0.2) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call...'

在我的网站中没有/sites/`的路由:这是一个外部网络服务错误,我想知道它的IP来解决问题。

我已经学会了这个,但是不起作用,我想我需要一些其他的代码

(我有 Rails 4.0.2,我将很快升级到 4.2.5。)

1- 在routes.rb,最后:

 match '*path', :to => 'application#routing_error', via: :all

2- 在application_ontroller:我记录了 IP,然后 如果我在生产中,我需要渲染 404.html,如果我在开发中,我需要正常渲染 rails 错误

  def routing_error(error = 'Routing error', status = :not_found, exception=nil)
    logger.debug { "---> I catch you #{request.remote_ip}" }
    render status: 404, file: "404.html"
  end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 routing


    【解决方案1】:

    解决方案:

    在 routes.rb 中

    class RoutingErrorConstrain
      def initialize
        @prodenv = Rails.env == "production"
      end
    
      def matches?(request)
        @prodenv
      end
    end
    
    MyApp::Application.routes.draw do
    
    ...
      match '*path', to: 'application#render_routing_error',
                     via: :all,
                     constraints: RoutingErrorConstrain.new
    ...
    end
    

    在 application_controller.rb 中:

      def render_routing_error
        logger.warn do "
            BAD IP: #{request.ip}. Remote_ip: #{request.remote_ip}"
        end
    
        respond_to do |format|
          format.html 
            { render file: "public/404.html", layout: false }
          format.all { render nothing: true, status: status }
        end
      end
    

    【讨论】:

      【解决方案2】:

      在您的application_controller 中只需编写以下代码 -

      rescue_from ActionController::RoutingError, with: lambda { |exception| render_error(404, exception) }
      
      def render_error(status, exception)
         respond_to do |format|
           format.html { render template: "public/#{status}", layout: false, status: status }
           format.all { render nothing: true, status: status }
         end
      end
      

      您可以在方法中添加一个条件来检查 rails 环境。

      希望这会有所帮助!

      【讨论】:

      • 我正在开发中对其进行测试,但它不起作用...¿?我在 'respond_to ..' 之前放了一个 'byebug' 并且没有执行 'render_error' 方法
      • 绝对不会在开发中执行,我一直在阅读 Rails 指南,在那里我可以找到更多像你这样的例子,以不同的方式对其进行测试......没有成功
      • 这永远不会运行,因为 ActionController::RoutingError 在请求被分派到任何控制器之前在路由阶段被抛出。
      猜你喜欢
      • 1970-01-01
      • 2017-05-19
      • 2015-07-17
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 2018-04-26
      • 2014-11-08
      相关资源
      最近更新 更多