Skip to content

Commit

Permalink
Add failed callback(s) into InvalidTransition exception
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswoodrich committed Oct 22, 2015
1 parent 5e6a8f0 commit b6d5a0d
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 10 deletions.
8 changes: 4 additions & 4 deletions lib/aasm/aasm.rb
Expand Up @@ -91,10 +91,10 @@ def aasm_fire_event(state_machine_name, event_name, options, *args, &block)
if new_state_name = event.fire(self, {:may_fire => may_fire_to}, *args)
aasm_fired(state_machine_name, event, old_state, new_state_name, options, *args, &block)
else
aasm_failed(state_machine_name, event_name, old_state)
aasm_failed(state_machine_name, event_name, old_state, event.failed_callbacks)
end
else
aasm_failed(state_machine_name, event_name, old_state)
aasm_failed(state_machine_name, event_name, old_state, event.failed_callbacks)
end
rescue StandardError => e
event.fire_callbacks(:error, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) || raise(e)
Expand Down Expand Up @@ -143,13 +143,13 @@ def aasm_fired(state_machine_name, event, old_state, new_state_name, options, *a
persist_successful
end

def aasm_failed(state_machine_name, event_name, old_state)
def aasm_failed(state_machine_name, event_name, old_state, failures = [])
if self.respond_to?(:aasm_event_failed)
self.aasm_event_failed(event_name, old_state.name)
end

if AASM::StateMachine[self.class][state_machine_name].config.whiny_transitions
raise AASM::InvalidTransition.new(self, event_name, state_machine_name)
raise AASM::InvalidTransition.new(self, event_name, state_machine_name, failures)
else
false
end
Expand Down
4 changes: 4 additions & 0 deletions lib/aasm/core/event.rb
Expand Up @@ -72,6 +72,10 @@ def transitions(definitions=nil, &block)
@transitions
end

def failed_callbacks
@transitions.flat_map(&:failures)
end

private

def attach_event_guards(definitions)
Expand Down
7 changes: 5 additions & 2 deletions lib/aasm/core/transition.rb
Expand Up @@ -2,12 +2,13 @@ module AASM::Core
class Transition
include DslHelper

attr_reader :from, :to, :event, :opts
attr_reader :from, :to, :event, :opts, :failures
alias_method :options, :opts

def initialize(event, opts, &block)
add_options_from_dsl(opts, [:on_transition, :guard, :after], &block) if block

@failures = []
@event = event
@from = opts[:from]
@to = opts[:to]
Expand Down Expand Up @@ -52,7 +53,9 @@ def invoke_callbacks_compatible_with_guard(code, record, args, options={})
case code
when Symbol, String
arity = record.send(:method, code.to_sym).arity
arity == 0 ? record.send(code) : record.send(code, *args)
result = (arity == 0 ? record.send(code) : result = record.send(code, *args))
failures << code unless result
result
when Proc
code.arity == 0 ? record.instance_exec(&code) : record.instance_exec(*args, &code)
when Array
Expand Down
12 changes: 8 additions & 4 deletions lib/aasm/errors.rb
Expand Up @@ -3,14 +3,18 @@ module AASM
class UnknownStateMachineError < RuntimeError; end

class InvalidTransition < RuntimeError
attr_reader :object, :event_name, :state_machine_name
attr_reader :object, :event_name, :state_machine_name, :failures

def initialize(object, event_name, state_machine_name)
@object, @event_name, @state_machine_name = object, event_name, state_machine_name
def initialize(object, event_name, state_machine_name, failures = [])
@object, @event_name, @state_machine_name, @failures = object, event_name, state_machine_name, failures
end

def message
"Event '#{event_name}' cannot transition from '#{object.aasm(state_machine_name).current_state}'"
"Event '#{event_name}' cannot transition from '#{object.aasm(state_machine_name).current_state}'#{reasoning}"
end

def reasoning
". Failed callback(s): #{@failures}." unless failures.empty?
end
end

Expand Down

0 comments on commit b6d5a0d

Please sign in to comment.