【问题标题】:rescue_from ActionController::RoutingError in Rails 4在 Rails 4 中救援来自 ActionController::RoutingError
【发布时间】:2014-11-08 14:03:51
【问题描述】:

我遇到以下错误:

ActionController::RoutingError (No route matches [GET] "/images/favicon.ico")

我想为不存在的链接显示 error404 页面。

我怎样才能做到这一点?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 ruby-on-rails-5 actioncontroller


    【解决方案1】:

    app/assets/images 中复制 favicon 图片 对我有用。

    【讨论】:

      【解决方案2】:

      application_controller.rb 中添加以下内容:

        # You want to get exceptions in development, but not in production.
        unless Rails.application.config.consider_all_requests_local
          rescue_from ActionController::RoutingError, with: -> { render_404  }
        end
      
        def render_404
          respond_to do |format|
            format.html { render template: 'errors/not_found', status: 404 }
            format.all { render nothing: true, status: 404 }
          end
        end
      

      我通常也会挽救以下异常,但这取决于你:

      rescue_from ActionController::UnknownController, with: -> { render_404  }
      rescue_from ActiveRecord::RecordNotFound,        with: -> { render_404  }
      

      创建错误控制器:

      class ErrorsController < ApplicationController
        def error_404
          render 'errors/not_found'
        end
      end
      

      然后在routes.rb

        unless Rails.application.config.consider_all_requests_local
          # having created corresponding controller and action
          get '*path', to: 'errors#error_404', via: :all
        end
      

      最后一件事是在/views/errors/ 下创建not_found.html.haml(或您使用的任何模板引擎):

        %span 404
        %br
        Page Not Found
      

      【讨论】:

      • 这在 Rails 4.2.5 中不起作用。我猜这是因为 ActionDispatch 在运行任何控制器代码之前引发了异常。
      • @depquid 我是在 Rails 4.0.x 时代写的,但刚刚用 Rails 4.2.5 测试过——我想你没有添加路由也没有创建errors_controller.rb :)如果是这种情况 - 请务必收回反对票,除非您有更多理由放弃它
      • 抱歉,我没有正确设置路由。但是,如果您直接路由到操作,为什么还要 rescue_from ActionController::RoutingError, with: -&gt; { render_404 }
      • 如果您需要在运行任何控制器代码之前(即在路由级别)捕获此问题,请参阅下面的@misu 答案以添加match '*path' =&gt; 'errors#error_404', via: :all
      • 当您的路径匹配所有内容 (get '*path', to: 'errors#error_404', via: :all) 时,您如何获得 ActionController::RoutingError
      【解决方案3】:

      @Andrey Deineko,您的解决方案似乎仅适用于在 conrtoller 内手动引发的 RoutingErrors。如果我尝试使用 url my_app/not_existing_path,我仍然会收到标准错误消息。

      我猜这是因为应用程序甚至没有到达控制器,因为 Rails 之前引发了错误。

      为我解决问题的trick 是在路由的end 处添加以下行:

      Rails.application.routes.draw do
        # existing paths
        match '*path' => 'errors#error_404', via: :all
      end
      

      捕获所有未预定义的请求。

      然后在ErrorsController中你可以使用respond_to来服务html、json...请求:

      class ErrorsController < ApplicationController
        def error_404
          @requested_path = request.path
          repond_to do |format|
            format.html
            format.json { render json: {routing_error: @requested_path} }
          end
        end
      end
      

      【讨论】:

      • 你能解释一下@requested_path = request.path及其对应的调用format.json { render json: {routing_error: @requested_path} }吗?
      • 我刚刚在模板中使用了@requested_path (error_404.html.haml)。至于 json,如果我确定我不希望返回完整页面,例如通过 ajax,我可以要求返回 json,并得到错误消息
      • @misu 这很完美,你在config/routes.rb 文件中添加它的技巧是关键
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 2017-04-10
      • 2013-03-05
      • 2018-08-12
      • 2023-01-13
      相关资源
      最近更新 更多