1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Response when error should be formatted properly in Rails API if local request

This commit is contained in:
Jorge Bejar 2015-07-06 21:33:19 -03:00
parent b79bfaadaf
commit 83b4e9073f
6 changed files with 44 additions and 10 deletions

View file

@ -69,15 +69,15 @@ module ActionDispatch
def default_path_parameters
if format = format_from_path_extension
{ 'format' => format }
{ format: format }
else
{}
end
end
def format_from_path_extension
path = @env['action_dispatch.original_path']
if match = path.match(/\.(\w+)$/)
path = @env['action_dispatch.original_path'] || @env['PATH_INFO']
if match = path && path.match(/\.(\w+)$/)
match.captures.first
end
end

View file

@ -38,9 +38,10 @@ module ActionDispatch
end
end
def initialize(app, routes_app = nil)
def initialize(app, routes_app = nil, api_only = false)
@app = app
@routes_app = routes_app
@api_only = api_only
end
def call(env)
@ -90,7 +91,19 @@ module ActionDispatch
)
file = "rescues/#{wrapper.rescue_template}"
if request.xhr?
if @api_only
body = {
:status => wrapper.status_code,
:error => Rack::Utils::HTTP_STATUS_CODES.fetch(wrapper.status_code, Rack::Utils::HTTP_STATUS_CODES[500]),
:exception => wrapper.exception.inspect,
:traces => traces
}
if content_type = request.formats.first
to_format = "to_#{content_type.to_sym}"
body = body.public_send(to_format)
end
format = "application/json"
elsif request.xhr?
body = template.render(template: file, layout: false, formats: [:text])
format = "text/plain"
else

View file

@ -661,10 +661,6 @@ class RespondToControllerTest < ActionController::TestCase
end
def test_variant_inline_syntax
get :variant_inline_syntax, format: :js
assert_equal "text/javascript", @response.content_type
assert_equal "js", @response.body
get :variant_inline_syntax
assert_equal "text/html", @response.content_type
assert_equal "none", @response.body
@ -674,6 +670,12 @@ class RespondToControllerTest < ActionController::TestCase
assert_equal "phone", @response.body
end
def test_variant_inline_syntax_with_format
get :variant_inline_syntax, format: :js
assert_equal "text/javascript", @response.content_type
assert_equal "js", @response.body
end
def test_variant_inline_syntax_without_block
get :variant_inline_syntax_without_block, params: { v: :phone }
assert_equal "text/html", @response.content_type

View file

@ -75,6 +75,13 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
end
end
class BoomerAPI < Boomer
def call(env)
env['action_dispatch.show_detailed_exceptions'] = @detailed
raise "puke!"
end
end
RoutesApp = Struct.new(:routes).new(SharedTestRoutes)
ProductionApp = ActionDispatch::DebugExceptions.new(Boomer.new(false), RoutesApp)
DevelopmentApp = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp)
@ -155,6 +162,17 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_match(/ActionController::ParameterMissing/, body)
end
test "rescue with json on API request" do
@app = ActionDispatch::DebugExceptions.new(BoomerAPI.new(true), RoutesApp, true)
get "/index.json", headers: { 'action_dispatch.show_exceptions' => true }
assert_response 500
assert_no_match(/<header>/, body)
assert_no_match(/<body>/, body)
assert_equal "application/json", response.content_type
assert_match(/RuntimeError: puke/, body)
end
test "rescue with text error for xhr request" do
@app = DevelopmentApp
xhr_request_env = {'action_dispatch.show_exceptions' => true, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'}

View file

@ -3272,6 +3272,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
expected_params = {
controller: 'downloads',
action: 'show',
format: 'tar',
id: '1'
}

View file

@ -57,7 +57,7 @@ module Rails
# Must come after Rack::MethodOverride to properly log overridden methods
middleware.use ::Rails::Rack::Logger, config.log_tags
middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app
middleware.use ::ActionDispatch::DebugExceptions, app
middleware.use ::ActionDispatch::DebugExceptions, app, config.api_only
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
unless config.cache_classes