如何捕获rails 6中的rack Range错误

of1yzvn4  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(304)

我有一个rails 6应用程序,用户可以上传csv文件。rails/rack对请求中可以包含的参数数量施加了限制,我已经将其设置为比可能提交到我的应用程序更大的大小。但是,如果上传的文件太大,我想返回一个友好的回复。
看起来我需要添加一些自定义中间件来捕获和解救错误,但我无法让代码正常工作-在没有调用解救块的情况下仍然会引发基本错误。
来自服务器的错误是:

Rack app error handling request { POST /[PATH_TO]/datasets }

# <RangeError: exceeded available parameter key space>

我的 app/middleware/catch_errors.rb 该文件基本上是从之前的so答案中提取的,在那里有人正在捕捉 ActionDispatch::ParamsParser::ParseError 在json中,但在 rescue block(我意识到在这种情况下可能无法正常工作,但这不是现在的问题):

class CatchErrors
  def initialize(_app)
    @app = _app
  end

  def call(_env)
    begin
      @app.call(_env)
    rescue RangeError => _error
      _error_output = "There were too many fields in the data you submitted: #{_error}"
      if env['HTTP_ACCEPT'] =~ /application\/html/
        Rails.logger.error("Caught RangeError: #{_error}")
        flash[:error_title] = 'Too many fields in your data'
        flash[:error_detail1] = _error_output
        render 'static_pages/error', status: :bad_request
      elsif env['HTTP_ACCEPT'] =~ /application\/json/
        return [
          :bad_request, { "Content-Type" => "application/json" },
          [ { status: :bad_request, error: _error_output }.to_json ]
        ]
      else
        raise _error
      end
    end
  end
end

我正在把它装进去 config.application.rb 这样地:

require_relative '../app/middleware/catch_errors'
...
config.middleware.use CatchErrors

我正在重置测试的大小限制 app/initializers/rack.rb 这样地:

if Rack::Utils.respond_to?("key_space_limit=")
  Rack::Utils.key_space_limit = 1
end

感谢您的帮助!

b5lpy0ml

b5lpy0ml1#

首先,执行命令以查看所有中间件:

bin/rails middleware
``` `config.middleware.use` 将中间件放在中间件堆栈的底部。正因为如此,它不能捕捉错误。尝试将其放置在顶部:

config.middleware.insert_before 0, CatchErrors

另一点要提的是,你可能需要 `config.middleware.move_after` 甚至 `config.middleware.delete` 一些中间件。例如,在修补时,我需要放置:

config.middleware.move_after CatchErrors, Rack::MiniProfiler

相关问题