From 24b29e094239ddb1bd7b6b4b04ef46ea7ee01220 Mon Sep 17 00:00:00 2001 From: Wildfalcon Date: Tue, 1 Dec 2009 10:31:27 +0000 Subject: [PATCH] Fireing an event now calls aasm_error_callback if an exception is raised and aasm_error_callback is defined --- lib/aasm/aasm.rb | 84 +++++++++++++++++++++++------------------- spec/unit/aasm_spec.rb | 14 +++++++ 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/lib/aasm/aasm.rb b/lib/aasm/aasm.rb index e92b8878..3e2aeb5c 100644 --- a/lib/aasm/aasm.rb +++ b/lib/aasm/aasm.rb @@ -130,12 +130,12 @@ def aasm_current_state=(state) def aasm_determine_state_name(state) case state - when Symbol, String - state - when Proc - state.call(self) - else - raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc." + when Symbol, String + state + when Proc + state.call(self) + else + raise NotImplementedError, "Unrecognized state-type given. Expected Symbol, String, or Proc." end end @@ -146,50 +146,58 @@ def aasm_state_object_for_state(name) end def aasm_fire_event(name, persist, *args) - old_state = aasm_state_object_for_state(aasm_current_state) - event = self.class.aasm_events[name] + begin + old_state = aasm_state_object_for_state(aasm_current_state) + event = self.class.aasm_events[name] - old_state.call_action(:exit, self) + old_state.call_action(:exit, self) - # new event before callback - event.call_action(:before, self) + # new event before callback + event.call_action(:before, self) - new_state_name = event.fire(self, *args) + new_state_name = event.fire(self, *args) - unless new_state_name.nil? - new_state = aasm_state_object_for_state(new_state_name) + unless new_state_name.nil? + new_state = aasm_state_object_for_state(new_state_name) - # new before_ callbacks - old_state.call_action(:before_exit, self) - new_state.call_action(:before_enter, self) + # new before_ callbacks + old_state.call_action(:before_exit, self) + new_state.call_action(:before_enter, self) - new_state.call_action(:enter, self) + new_state.call_action(:enter, self) - persist_successful = true - if persist - persist_successful = set_aasm_current_state_with_persistence(new_state_name) - event.execute_success_callback(self) if persist_successful - else - self.aasm_current_state = new_state_name - end + persist_successful = true + if persist + persist_successful = set_aasm_current_state_with_persistence(new_state_name) + event.execute_success_callback(self) if persist_successful + else + self.aasm_current_state = new_state_name + end + + if persist_successful + old_state.call_action(:after_exit, self) + new_state.call_action(:after_enter, self) + event.call_action(:after, self) - if persist_successful - old_state.call_action(:after_exit, self) - new_state.call_action(:after_enter, self) - event.call_action(:after, self) + self.aasm_event_fired(name, old_state.name, self.aasm_current_state) if self.respond_to?(:aasm_event_fired) + else + self.aasm_event_failed(name, old_state.name) if self.respond_to?(:aasm_event_failed) + end - self.aasm_event_fired(name, old_state.name, self.aasm_current_state) if self.respond_to?(:aasm_event_fired) + persist_successful else - self.aasm_event_failed(name, old_state.name) if self.respond_to?(:aasm_event_failed) - end + if self.respond_to?(:aasm_event_failed) + self.aasm_event_failed(name, old_state.name) + end - persist_successful - else - if self.respond_to?(:aasm_event_failed) - self.aasm_event_failed(name, old_state.name) + false + end + rescue => e + if self.responds_to?(:aasm_error_callback) + self.aasm_error_callback(e) + else + raise e end - - false end end end diff --git a/spec/unit/aasm_spec.rb b/spec/unit/aasm_spec.rb index c9f12de9..585aba2f 100644 --- a/spec/unit/aasm_spec.rb +++ b/spec/unit/aasm_spec.rb @@ -292,6 +292,20 @@ def @foo.aasm_event_fired(event, from, to) @foo.should_not_receive(:aasm_event_fired) @foo.close! end + + it "should run aasm_error_callback if an exception is raised" do + @foo.stub!(:enter).and_raise(StandardError) + @foo.stub!(:responds_to?).with(:aasm_error_callback).and_return(true) + @foo.should_receive(:aasm_error_callback) + @foo.close! + end + + it "should propograte an exception if aasm_error_callback is not defined" do + @foo.stub!(:enter).and_raise(StandardError) + @foo.stub!(:responds_to?).with(:aasm_error_callback).and_return(false) + @foo.should_not_receive(:aasm_error_callback) + lambda{@foo.close!}.should raise_error + end end describe "with aasm_event_failed defined" do