diff --git a/lib/lotus/action/throwable.rb b/lib/lotus/action/throwable.rb index 07f5dbc9..30f2e6f8 100644 --- a/lib/lotus/action/throwable.rb +++ b/lib/lotus/action/throwable.rb @@ -24,10 +24,10 @@ def self.extended(base) # Action handled exceptions. # - # When an handled exception is raised during #call execution, it will be + # When a handled exception is raised during #call execution, it will be # translated into the associated HTTP status. # - # By default there aren't handled exceptions, all the errors are threaded + # By default there aren't handled exceptions, all the errors are treated # as a Server Side Error (500). # # @api private @@ -37,6 +37,19 @@ def self.extended(base) # @see Lotus::Action::Throwable.handle_exception class_attribute :handled_exceptions self.handled_exceptions = Controller.handled_exceptions.dup + + # Action-level setting for handling exceptions. + # + # When an exception is raised during a #call execution it will be + # translated into an associated HTTP status by default. You may + # want to disable this behavior for your testes. + # + # @api private + # @since 0.2.0 + # + # @see Lotus::Controller.handle_exceptions + class_attribute :handle_exceptions + self.handle_exceptions = Controller.handle_exceptions end end @@ -123,6 +136,7 @@ def _rescue end def _handle_exception(exception) + raise unless self.class.handle_exceptions throw self.class.handled_exceptions.fetch(exception.class, 500) end end diff --git a/lib/lotus/controller.rb b/lib/lotus/controller.rb index 8476cb69..8ec18940 100644 --- a/lib/lotus/controller.rb +++ b/lib/lotus/controller.rb @@ -29,10 +29,10 @@ module Controller include Utils::ClassAttribute # Global handled exceptions. - # When an handled exception is raised during #call execution, it will be + # When a handled exception is raised during #call execution, it will be # translated into the associated HTTP status. # - # By default there aren't handled exceptions, all the errors are threaded + # By default there aren't handled exceptions, all the errors are treated # as a Server Side Error (500). # # **Important:** Be sure to set this configuration, **before** the actions @@ -60,6 +60,37 @@ module Controller class_attribute :handled_exceptions self.handled_exceptions = {} + # Global setting for handling exceptions. + # + # When an exception is raised during a #call execution it will be + # translated into an associated HTTP status by default. You may want to + # disable this behavior for your testes. + # + # **Important:** Be sure to set this configuration, **before** the actions + # and controllers of your application are loaded. + # + # @since 0.2.0 + # + # @see Lotus::Action::Throwable + # + # @example + # require 'lotus/controller' + # + # Lotus::Controller.handle_exceptions = false + # + # class Show + # include Lotus::Action + # + # def call(params) + # # ... + # raise RecordNotFound.new + # end + # end + # + # Show.new.call({id: 1}) # => ERROR RecordNotFound: RecordNotFound + class_attribute :handle_exceptions + self.handle_exceptions = true + def self.included(base) base.class_eval do include Dsl diff --git a/test/action_test.rb b/test/action_test.rb index b1a89f8a..12f64f5e 100644 --- a/test/action_test.rb +++ b/test/action_test.rb @@ -16,6 +16,22 @@ response[0].must_equal 500 response[2].must_equal ['Internal Server Error'] end + + describe 'when exception handling code is disabled' do + before do + ErrorCallAction.handle_exceptions = false + end + + after do + ErrorCallAction.handle_exceptions = true + end + + it 'should raise an actual exception' do + proc { + ErrorCallAction.new.call({}) + }.must_raise RuntimeError + end + end end describe '#expose' do