Rails Rails 5 如何自定义处理 ActionDispatch::ParamsParser::ParseError 异常

charleszhang · 2016年10月19日 · 最后由 mimosa 回复于 2016年10月20日 · 2729 次阅读

参考这个方式处理 https://robots.thoughtbot.com/catching-json-parse-errors-with-custom-middleware ,提示 “No such middleware to insert before: ActionDispatch::ParamsParser”。

运行 rake middleware 结果如下:(确实没有 ActionDispatch::ParamsParser)

use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Sprockets::Rails::QuietAssets
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
run RailsChecheDataaudit::Application.routes

改为

config.middleware.insert_before ActionDispatch::Static, 'CatchJsonParseErrors'

仍然无法捕获异常。应该如何处理?

# insert middleware wherever you want in the stack, optionally pass initialization arguments
  config.middleware.insert_before ActionDispatch::ParamsParser, Rack::Robustness do |c|
    c.no_catch_all
    c.on(ArgumentError) { |ex| 400 }
    c.content_type 'application/json'
    c.body{ |ex| 
      { 
        error: ex.message
      }.to_json
    }
    c.ensure(true) { |ex| env['rack.errors'].write(ex.message) }
  end if Rails.env.production? # 生产环境

#1 楼 @mimosa 还是提示 “No such middleware to insert before: ActionDispatch::ParamsParser (RuntimeError)”😂

抱歉,url 刚刚编辑有误,更新了

#2 楼 @charleszhang Rails5 移除了 ActionDispatch::ParamsParser

#4 楼 @mimosa 是的,正确的处理方式是啥样呢?

@charleszhang 试试呗。😔

# in app/middleware/catch_json_parse_errors.rb
class CatchJsonParseErrors
  def initialize(app)
    @app = app
  end

  def call(env)
    begin
      @app.call(env)
    rescue ActionDispatch::Http::Parameters::ParseError => e
      if env['HTTP_ACCEPT'] =~ /application\/json/
        error_output = "There was a problem in the JSON you submitted: #{e.message}"
        return [
          400, { "Content-Type" => "application/json" },
          [ { status: 400, error: error_output }.to_json ]
        ]
      else
        raise error
      end
    end
  end
end


# in config/application.rb
module YourApp
  class Application < Rails::Application
    # ...
    config.middleware.insert_after ActionDispatch::ShowExceptions, 'CatchJsonParseErrors'
    # ...
  end
end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号