如何在 Rails 6 中捕获 Rack RangeError
How to catch a Rack RangeError in Rails 6
我有一个 Rails 6 应用程序,用户可以将 CSV 文件上传到该应用程序。 Rails/Rack 对可以包含在请求中的参数数量施加了限制,并且我将其设置为比可能提交到我的应用程序的尺寸更大的尺寸。但是,如果上传的文件太大,我希望 return 友好回复。
看来我需要添加一些自定义中间件来捕获和挽救错误,但我无法使代码正常工作 - 基本错误在我的救援块未被调用的情况下仍然出现。
来自服务器的错误是:
Rack app error handling request { POST /[PATH_TO]/datasets }
#<RangeError: exceeded available parameter key space>
我的 app/middleware/catch_errors.rb
文件中的代码基本上取自 ,有人在 JSON 中捕获了 ActionDispatch::ParamsParser::ParseError
,但 [=] 中有我自己的代码17=] 块(我意识到在这种情况下可能无法正常工作,但这不是现在的问题):
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
感谢收到任何帮助!
首先,执行命令查看所有中间件:
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
我有一个 Rails 6 应用程序,用户可以将 CSV 文件上传到该应用程序。 Rails/Rack 对可以包含在请求中的参数数量施加了限制,并且我将其设置为比可能提交到我的应用程序的尺寸更大的尺寸。但是,如果上传的文件太大,我希望 return 友好回复。
看来我需要添加一些自定义中间件来捕获和挽救错误,但我无法使代码正常工作 - 基本错误在我的救援块未被调用的情况下仍然出现。
来自服务器的错误是:
Rack app error handling request { POST /[PATH_TO]/datasets }
#<RangeError: exceeded available parameter key space>
我的 app/middleware/catch_errors.rb
文件中的代码基本上取自 ActionDispatch::ParamsParser::ParseError
,但 [=] 中有我自己的代码17=] 块(我意识到在这种情况下可能无法正常工作,但这不是现在的问题):
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
感谢收到任何帮助!
首先,执行命令查看所有中间件:
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