Skip to content

Commit

Permalink
add ability to specify custom exception handlers
Browse files Browse the repository at this point in the history
change approach in exception handlers

- Allow only method name or status code as handler
- Don't require to return array with code and body

use handler as void function

Another change in exception handling apporach

- Remove `exception_code` in favour of `exception_handler` in Configuration
- Add Thorwable::Handlers, which defines handlers for all status codes
- Remove ability to specify handlers by status code in favour of explicit handlers

Rename class name to reflect recent changes

ruby 2.0.0 compatibility changes

Revert "Another change in exception handling apporach"

This reverts commit 3ee3620.

Revert "Rename class name to reflect recent changes"

This reverts commit e3c9d82.

Revert "ruby 2.0.0 compatibility changes"

This reverts commit 7729415.

small code cleanup

Don’t use protected handled_exceptions method

Rename `exception_code` to `exception_code` which returns either exception code, or handler name
  • Loading branch information
krzyzak authored and jodosha committed Oct 6, 2014
1 parent 77e82a2 commit 98896cc
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 15 deletions.
13 changes: 10 additions & 3 deletions lib/lotus/action/throwable.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ def handle_exception(exception)
# @see Lotus::Controller#handled_exceptions # @see Lotus::Controller#handled_exceptions
# @see Lotus::Action::Throwable#handle_exception # @see Lotus::Action::Throwable#handle_exception
# @see Lotus::Http::Status:ALL # @see Lotus::Http::Status:ALL
def halt(code) def halt(code = nil)
status(*Http::Status.for_code(code)) status(*Http::Status.for_code(code)) if code
throw :halt throw :halt
end end


Expand Down Expand Up @@ -124,7 +124,14 @@ def _dump_exception(exception)
# @api private # @api private
def _handle_exception(exception) def _handle_exception(exception)
raise unless configuration.handle_exceptions raise unless configuration.handle_exceptions
halt configuration.exception_code(exception.class) handler = configuration.exception_handler(exception.class)

if handler.is_a?(Symbol)
method(handler).call(exception)
halt
else
halt handler
end
end end
end end
end end
Expand Down
2 changes: 1 addition & 1 deletion lib/lotus/controller/configuration.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def handle_exception(exception)
# @api private # @api private
# #
# @see Lotus::Controller::Configuration#handle_exception # @see Lotus::Controller::Configuration#handle_exception
def exception_code(exception) def exception_handler(exception)
@handled_exceptions.fetch(exception) { DEFAULT_ERROR_CODE } @handled_exceptions.fetch(exception) { DEFAULT_ERROR_CODE }
end end


Expand Down
30 changes: 23 additions & 7 deletions test/action_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@
response[2].must_equal ['Hi from TestAction!'] response[2].must_equal ['Hi from TestAction!']
end end


it 'returns an HTTP 500 status code when an exception is raised' do
response = ErrorCallAction.new.call({})

response[0].must_equal 500
response[2].must_equal ['Internal Server Error']
end

it 'exposes validation errors' do it 'exposes validation errors' do
action = ParamsValidationAction.new action = ParamsValidationAction.new
code, _, _ = action.call({}) code, _, _ = action.call({})
Expand All @@ -45,6 +38,29 @@
action.errors.for(:email).must_include Lotus::Validations::Error.new(:email, :presence, true, nil) action.errors.for(:email).must_include Lotus::Validations::Error.new(:email, :presence, true, nil)
end end


describe 'when exception handling code is enabled' do
it 'returns an HTTP 500 status code when an exception is raised' do
response = ErrorCallAction.new.call({})

response[0].must_equal 500
response[2].must_equal ['Internal Server Error']
end

it 'handles exception with specified method' do
response = ErrorCallWithMethodNameAsHandlerAction.new.call({})

response[0].must_equal 501
response[2].must_equal ['Please go away!']
end

it 'handles exception with specified status code' do
response = ErrorCallWithSpecifiedStatusCodeAction.new.call({})

response[0].must_equal 422
response[2].must_equal ['Unprocessable Entity']
end
end

describe 'when exception handling code is disabled' do describe 'when exception handling code is disabled' do
before do before do
ErrorCallAction.configuration.handle_exceptions = false ErrorCallAction.configuration.handle_exceptions = false
Expand Down
8 changes: 4 additions & 4 deletions test/configuration_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ module CustomAction
end end
end end


describe 'exception_code' do describe 'exception_handler' do
describe 'when the given error is unknown' do describe 'when the given error is unknown' do
it 'returns the default value' do it 'returns the default value' do
@configuration.exception_code(Exception).must_equal 500 @configuration.exception_handler(Exception).must_equal 500
end end
end end


Expand All @@ -56,8 +56,8 @@ module CustomAction
@configuration.handle_exception NotImplementedError => 400 @configuration.handle_exception NotImplementedError => 400
end end


it 'returns the default value' do it 'returns given value' do
@configuration.exception_code(NotImplementedError).must_equal 400 @configuration.exception_handler(NotImplementedError).must_equal 400
end end
end end
end end
Expand Down
25 changes: 25 additions & 0 deletions test/fixtures.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ def call(params)
end end
end end


class ErrorCallWithMethodNameAsHandlerAction
include Lotus::Action

handle_exception StandardError => :handler

def call(params)
raise StandardError
end

private
def handler(exception)
status 501, 'Please go away!'
end
end

class ErrorCallWithSpecifiedStatusCodeAction
include Lotus::Action

handle_exception StandardError => 422

def call(params)
raise StandardError
end
end

class ExposeAction class ExposeAction
include Lotus::Action include Lotus::Action


Expand Down

0 comments on commit 98896cc

Please sign in to comment.