Skip to content

Commit

Permalink
Support choices that do not have a default defined
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrock committed Aug 2, 2024
1 parent 35c2045 commit 1dfe07e
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 6 deletions.
13 changes: 11 additions & 2 deletions lib/floe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,17 @@ module Floe
class Error < StandardError; end
class InvalidWorkflowError < Error; end
class InvalidExecutionInput < Error; end
class PathError < Error; end
class ExecutionError < Error; end

class ExecutionError < Error
attr_reader :floe_error

def initialize(message, floe_error = "States.Runtime")
super(message)
@floe_error = floe_error
end
end

class PathError < ExecutionError; end

def self.logger
@logger ||= NullLogger.new
Expand Down
4 changes: 2 additions & 2 deletions lib/floe/validation_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def invalid_field_error!(field_name, field_value = nil, comment = nil)
self.class.invalid_field_error!(name, field_name, field_value, comment)
end

def runtime_field_error!(field_name, field_value, comment)
raise Floe::ExecutionError, self.class.field_error_text(name, field_name, field_value, comment)
def runtime_field_error!(field_name, field_value, comment, floe_error: "States.Runtime")
raise Floe::ExecutionError.new(self.class.field_error_text(name, field_name, field_value, comment), floe_error)
end

def workflow_state?(field_value, workflow)
Expand Down
4 changes: 2 additions & 2 deletions lib/floe/workflow/state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def run_nonblock!(context)
return Errno::EAGAIN unless ready?(context)

finish(context)
rescue Floe::Error => e
rescue Floe::ExecutionError => e
mark_error(context, e)
end

Expand Down Expand Up @@ -82,7 +82,7 @@ def mark_finished(context)
def mark_error(context, exception)
# InputPath or OutputPath were bad.
context.next_state = nil
context.output = {"Error" => "States.Runtime", "Cause" => exception.message}
context.output = {"Error" => exception.floe_error, "Cause" => exception.message}
# Since finish threw an exception, super was never called. Calling that now.
mark_finished(context)
end
Expand Down
1 change: 1 addition & 0 deletions lib/floe/workflow/states/choice.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def finish(context)
output = output_path.value(context, input)
next_state = choices.detect { |choice| choice.true?(context, output) }&.next || default

runtime_field_error!("Default", nil, "not defined and no match found", :floe_error => "States.NoChoiceMatched") if next_state.nil?
context.next_state = next_state
context.output = output
super
Expand Down
30 changes: 30 additions & 0 deletions spec/workflow/states/choice_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,35 @@
expect(ctx.next_state).to eq("DefaultState")
end
end

context "with no default" do
let(:payload) do
{
"Choice1" => {"Type" => "Choice", "Choices" => choices},
"FirstMatchState" => {"Type" => "Succeed"},
"SecondMatchState" => {"Type" => "Succeed"}
}
end

context "with an input value matching a condition" do
let(:input) { {"foo" => 1} }

it "returns the next state" do
state.run_nonblock!(ctx)
expect(ctx.next_state).to eq("FirstMatchState")
end
end

context "with an input value not matching a condition" do
let(:input) { {"foo" => 3} }

it "throws error when not found" do
workflow.run_nonblock
expect(ctx.failed?).to eq(true)
expect(ctx.output["Error"]).to eq("States.NoChoiceMatched")
expect(ctx.output["Cause"]).to eq("States.Choice1 field \"Default\" not defined and no match found")
end
end
end
end
end

0 comments on commit 1dfe07e

Please sign in to comment.