diff --git a/lib/leopard/message_wrapper.rb b/lib/leopard/message_wrapper.rb index 3f1279b..793f5a9 100644 --- a/lib/leopard/message_wrapper.rb +++ b/lib/leopard/message_wrapper.rb @@ -31,11 +31,11 @@ def respond(payload) raw.respond(serialize(payload)) end - # @param err [String, Exception] The error message or exception to respond with. + # @param err [Object] The error payload to respond with. # # @return [void] - def respond_with_error(err) - raw.respond_with_error(err.to_s) + def respond_with_error(err, &) + raw.respond_with_error(err, &) end private diff --git a/lib/leopard/nats_api_server.rb b/lib/leopard/nats_api_server.rb index 26b8671..374165d 100644 --- a/lib/leopard/nats_api_server.rb +++ b/lib/leopard/nats_api_server.rb @@ -313,7 +313,7 @@ def handle_message(raw_msg, handler) process_result(wrapper, result) rescue StandardError => e logger.error 'Error processing message: ', e - wrapper.respond_with_error(e.message) + wrapper.respond_with_error(e) end # Processes the result of the handler execution. diff --git a/test/lib/message_wrapper.rb b/test/lib/message_wrapper.rb index 7c94d88..a5cc268 100644 --- a/test/lib/message_wrapper.rb +++ b/test/lib/message_wrapper.rb @@ -4,7 +4,7 @@ require 'leopard/message_wrapper' class FakeMsg - attr_reader :data, :responded_payload, :error_args + attr_reader :data, :responded_payload, :error_args, :error_block_called_with attr_accessor :header def initialize(data, header = {}) @@ -18,6 +18,11 @@ def respond(payload) def respond_with_error(err) @error_args = [err] + return unless block_given? + + yielded_error = {} + yield yielded_error + @error_block_called_with = yielded_error end end @@ -63,10 +68,23 @@ def respond_with_error(err) assert_equal ['fail'], msg.error_args end - it 'coerces exception objects to strings when responding with error' do + it 'passes exception objects through when responding with error' do err = StandardError.new('broken') wrapper.respond_with_error(err) - assert_equal ['broken'], msg.error_args + assert_equal [err], msg.error_args + end + + it 'passes hash payloads through when responding with error' do + err = { 'description' => 'broken', 'code' => 422 } + wrapper.respond_with_error(err) + + assert_equal [err], msg.error_args + end + + it 'forwards blocks when responding with error' do + wrapper.respond_with_error(code: 422) { |error| error[:code] = 422 } + + assert_equal({ code: 422 }, msg.error_block_called_with) end end diff --git a/test/lib/nats_api_server.rb b/test/lib/nats_api_server.rb index 1fc732b..3d00a5a 100755 --- a/test/lib/nats_api_server.rb +++ b/test/lib/nats_api_server.rb @@ -139,12 +139,15 @@ def call(wrapper) it 'responds with error when handler raises' do raw_msg = Object.new - wrapper = Minitest::Mock.new - wrapper.expect(:respond_with_error, nil, ['boom']) + err = nil + wrapper = Object.new + wrapper.define_singleton_method(:respond_with_error) { |raised| err = raised } Rubyists::Leopard::MessageWrapper.stub(:new, wrapper) do @instance.send(:handle_message, raw_msg, proc { raise 'boom' }) end - wrapper.verify + + assert_instance_of RuntimeError, err + assert_equal 'boom', err.message end it 'responds when processing Success result' do @@ -162,4 +165,13 @@ def call(wrapper) @instance.send(:process_result, wrapper, result) wrapper.verify end + + it 'passes hash failures through unchanged' do + err = { code: 422, description: 'invalid' } + wrapper = Minitest::Mock.new + wrapper.expect(:respond_with_error, nil, [err]) + result = Rubyists::Leopard::NatsApiServer::Failure.new(err) + @instance.send(:process_result, wrapper, result) + wrapper.verify + end end