Skip to content

Commit dcc1131

Browse files
authored
Merge pull request #827 from senid231/render_results_server_error
call server_error_callbacks on handle_exceptions in controller
2 parents 539051b + 115869b commit dcc1131

3 files changed

Lines changed: 48 additions & 0 deletions

File tree

lib/jsonapi/acts_as_resource_controller.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,27 @@ def handle_exceptions(e)
266266
if JSONAPI.configuration.exception_class_whitelisted?(e)
267267
fail e
268268
else
269+
(self.class.server_error_callbacks || []).each { |callback|
270+
safe_run_callback(callback, e)
271+
}
272+
269273
internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e)
270274
Rails.logger.error { "Internal Server Error: #{e.message} #{e.backtrace.join("\n")}" }
271275
render_errors(internal_server_error.errors)
272276
end
273277
end
274278
end
275279

280+
def safe_run_callback(callback, error)
281+
begin
282+
callback.call(error)
283+
rescue => e
284+
Rails.logger.error { "Error in error handling callback: #{e.message} #{e.backtrace.join("\n")}" }
285+
internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e)
286+
render_errors(internal_server_error.errors)
287+
end
288+
end
289+
276290
# Pass in a methods or a block to be run when an exception is
277291
# caught that is not a JSONAPI::Exceptions::Error
278292
# Useful for additional logging or notification configuration that

test/controllers/controller_test.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,25 @@ def test_on_server_error_method_callback_with_exception
123123
JSONAPI.configuration = original_config
124124
end
125125

126+
def test_on_server_error_method_callback_with_exception_on_serialize
127+
original_config = JSONAPI.configuration.dup
128+
JSONAPI.configuration.exception_class_whitelist = []
129+
$PostSerializerRaisesErrors = true
130+
131+
#ignores methods that don't exist
132+
@controller.class.on_server_error :set_callback_message, :a_bogus_method
133+
@controller.class.instance_variable_set(:@callback_message, "none")
134+
135+
assert_cacheable_get :index
136+
assert_equal "Sent from method", @controller.class.instance_variable_get(:@callback_message)
137+
138+
# test that it renders the default server error response
139+
assert_equal "Internal Server Error", json_response['errors'][0]['title']
140+
ensure
141+
$PostSerializerRaisesErrors = false
142+
JSONAPI.configuration = original_config
143+
end
144+
126145
def test_on_server_error_callback_without_exception
127146

128147
callback = Proc.new { @controller.class.instance_variable_set(:@callback_message, "Sent from block") }

test/fixtures/active_record.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ class PostsController < BaseController
580580

581581
class SpecialError < StandardError; end
582582
class SubSpecialError < PostsController::SpecialError; end
583+
class SerializeError < StandardError; end
583584

584585
# This is used to test that classes that are whitelisted are reraised by
585586
# the operations dispatcher.
@@ -600,6 +601,20 @@ def handle_exceptions(e)
600601
def self.set_callback_message(error)
601602
@callback_message = "Sent from method"
602603
end
604+
605+
def resource_serializer_klass
606+
PostSerializer
607+
end
608+
end
609+
610+
class PostSerializer < JSONAPI::ResourceSerializer
611+
def initialize(*)
612+
if $PostSerializerRaisesErrors
613+
raise PostsController::SerializeError
614+
else
615+
super
616+
end
617+
end
603618
end
604619

605620
class CommentsController < JSONAPI::ResourceController

0 commit comments

Comments
 (0)