Permalink
Browse files

add ability to specify custom exception handlers

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 2, 2014
1 parent 77e82a2 commit 98896cc19825d0eb1cad9487d1fbd87e85ecccc9
Showing with 63 additions and 15 deletions.
  1. +10 −3 lib/lotus/action/throwable.rb
  2. +1 −1 lib/lotus/controller/configuration.rb
  3. +23 −7 test/action_test.rb
  4. +4 −4 test/configuration_test.rb
  5. +25 −0 test/fixtures.rb
@@ -74,8 +74,8 @@ def handle_exception(exception)
# @see Lotus::Controller#handled_exceptions
# @see Lotus::Action::Throwable#handle_exception
# @see Lotus::Http::Status:ALL
def halt(code)
status(*Http::Status.for_code(code))
def halt(code = nil)
status(*Http::Status.for_code(code)) if code
throw :halt
end
@@ -124,7 +124,14 @@ def _dump_exception(exception)
# @api private
def _handle_exception(exception)
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
@@ -192,7 +192,7 @@ def handle_exception(exception)
# @api private
#
# @see Lotus::Controller::Configuration#handle_exception
def exception_code(exception)
def exception_handler(exception)
@handled_exceptions.fetch(exception) { DEFAULT_ERROR_CODE }
end
View
@@ -30,13 +30,6 @@
response[2].must_equal ['Hi from TestAction!']
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
action = ParamsValidationAction.new
code, _, _ = action.call({})
@@ -45,6 +38,29 @@
action.errors.for(:email).must_include Lotus::Validations::Error.new(:email, :presence, true, nil)
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
before do
ErrorCallAction.configuration.handle_exceptions = false
@@ -44,10 +44,10 @@ module CustomAction
end
end
describe 'exception_code' do
describe 'exception_handler' do
describe 'when the given error is unknown' do
it 'returns the default value' do
@configuration.exception_code(Exception).must_equal 500
@configuration.exception_handler(Exception).must_equal 500
end
end
@@ -56,8 +56,8 @@ module CustomAction
@configuration.handle_exception NotImplementedError => 400
end
it 'returns the default value' do
@configuration.exception_code(NotImplementedError).must_equal 400
it 'returns given value' do
@configuration.exception_handler(NotImplementedError).must_equal 400
end
end
end
View
@@ -101,6 +101,31 @@ def call(params)
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
include Lotus::Action

0 comments on commit 98896cc

Please sign in to comment.