为 422 错误生成错误页面

jas*_*328 2 ruby routes ruby-on-rails ruby-on-rails-4 http-status-code-422

我目前正在为 500 和 404 错误生成动态错误页面。我想将其扩展为 422 错误。这是我们目前所拥有的。

配置/应用程序.rb

config.exceptions_app = self.routes
Run Code Online (Sandbox Code Playgroud)

控制器/errors_controller.rb

class ErrorsController < ApplicationController
  def not_found
    render status: 404
  end

  def internal_server_error
    render status: 500
  end

  def unacceptable
    render status: 422
  end
end
Run Code Online (Sandbox Code Playgroud)

路由文件

get '/404' => 'errors#not_found'
get '/500' => 'errors#internal_server_error'
get '/422' => 'errors#unacceptable'
Run Code Online (Sandbox Code Playgroud)

public/422.html 页面已被删除。错误视图页面已创建,但为简洁起见省略。当出现 404 或 500 错误时,会显示错误页面。但是,当我收到 422 错误时,我会看到以下错误页面。

在此处输入图片说明

我已经看到许多实施这种相同方法的教程并且它有效。但是,我收到的是生成的 Rails 错误,而不是我创建的错误页面。出了什么问题,我该如何解决?

我看过的教程:

art*_*wis 5

我是另一位与 @jason328 合作的开发人员。结果证明这是一个多部分的问题,首先是一般的 422 错误,然后是 Rails 正在引发ActiveRecord::InvalidAuthenticityToken而不呈现适当页面的特定场景。

1. 一般422错误

Rails 错误页面

我们通过设置在本地开发环境中暂时摆脱了这一点config.consider_all_requests_local = false。但是,我们没有得到我们的自定义错误页面,而是得到了一个空白的白页。

空白的白页

根据这个 Stack Overflow 问题,我们需要match '/422', to: 'errors#unprocessable_entity', via: :all路由而不是get '/422' => 'errors#unprocessable_entity'.

此时,通用 422 错误按其应有的方式执行。我们设置了一个控制器动作,ActiveRecord::InvalidAuthenticityToken当你点击它时就会立即触发,并呈现我们自定义的 422 页面。因此,对于通常遇到 422 错误问题的任何人来说,以上内容应该涵盖了您。

2. 无效的AuthenticityToken

但由于 422 错误的常见原因实际上是InvalidAuthenticityToken在野外出现错误,因此似乎值得描述我们所看到的其余问题。在应用程序产生自己的InvalidAuthenticityToken错误的实际场景中,我们现在得到一个纯文本的 500 错误,而不是我们自定义的 422 页面。

纯文本 500 错误

我们能够将其追溯到FAILSAFE_RESPONSEin ActionDispatch::ShowExceptions#render_exception。这是 Rails 接受抛出的异常并将其转换为[status, body, headers]响应数组的地方。如果在此期间抛出另一个异常,而不是陷入无限循环,它会放弃并返回FAILSAFE_RESPONSE。在这种情况下,InvalidAuthenticityToken将响应放在一起时抛出了另一个错误。

此时,是时候制定:rescue_from策略了:

rescue_from ActionController::InvalidAuthenticityToken,
            with: :rescue_invalid_authenticity_token

def rescue_invalid_authenticity_token
  #...notify services as if this error weren't being rescued

  redirect_to '/422'
end
Run Code Online (Sandbox Code Playgroud)

使用重定向来防止我们InvalidAuthenticityToken在同一请求中出现更多错误。