Add class level case operator support for error dispatching in Rescuable

This commit is contained in:
Genadi Samokovarov 2014-12-09 12:04:50 +02:00
parent 6f4fd2c632
commit dd96e8e333
3 changed files with 45 additions and 4 deletions

View File

@ -1,3 +1,19 @@
* Added support for error dispatcher classes in ActiveSupport::Rescuable. Now it acts closer to Ruby's rescue.
class BaseController < ApplicationController
module ErrorDispatcher
def self.===(other)
Exception === other && other.respond_to?(:status)
end
end
rescue_from ErrorDispatcher do |error|
render status: error.status, json: { error: error.to_s }
end
end
*Genadi Samokovarov*
* Added `#verified` and `#valid_message?` methods to `ActiveSupport::MessageVerifier`
Previously, the only way to decode a message with `ActiveSupport::MessageVerifier` was to use `#verify`, which would raise an exception on invalid messages. Now `#verified` can also be used, which returns `nil` on messages that cannot be decoded.

View File

@ -60,7 +60,7 @@ module ActiveSupport
end
klasses.each do |klass|
key = if klass.is_a?(Class) && klass <= Exception
key = if klass.is_a?(Module) && klass.respond_to?(:===)
klass.name
elsif klass.is_a?(String)
klass
@ -101,7 +101,7 @@ module ActiveSupport
# itself when rescue_from CONSTANT is executed.
klass = self.class.const_get(klass_name) rescue nil
klass ||= klass_name.constantize rescue nil
exception.is_a?(klass) if klass
klass === exception if klass
end
case rescuer

View File

@ -12,6 +12,12 @@ end
class CoolError < StandardError
end
module WeirdError
def self.===(other)
Exception === other && other.respond_to?(:weird?)
end
end
class Stargate
attr_accessor :result
@ -29,6 +35,10 @@ class Stargate
@result = e.message
end
rescue_from WeirdError do
@result = 'weird'
end
def dispatch(method)
send(method)
rescue Exception => e
@ -47,6 +57,16 @@ class Stargate
raise MadRonon.new("dex")
end
def weird
StandardError.new.tap do |exc|
def exc.weird?
true
end
raise exc
end
end
def sos
@result = 'killed'
end
@ -91,14 +111,19 @@ class RescuableTest < ActiveSupport::TestCase
assert_equal 'dex', @stargate.result
end
def test_rescue_from_error_dispatchers_with_case_operator
@stargate.dispatch :weird
assert_equal 'weird', @stargate.result
end
def test_rescues_defined_later_are_added_at_end_of_the_rescue_handlers_array
expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon"]
expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon", "WeirdError"]
result = @stargate.send(:rescue_handlers).collect(&:first)
assert_equal expected, result
end
def test_children_should_inherit_rescue_definitions_from_parents_and_child_rescue_should_be_appended
expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon", "CoolError"]
expected = ["WraithAttack", "WraithAttack", "NuclearExplosion", "MadRonon", "WeirdError", "CoolError"]
result = @cool_stargate.send(:rescue_handlers).collect(&:first)
assert_equal expected, result
end