Skip to content

Commit

Permalink
Use ConverterWrapper in Workflow::Errors and fabricators
Browse files Browse the repository at this point in the history
  • Loading branch information
antstorm committed Mar 3, 2022
1 parent 8464638 commit 78a9250
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 26 deletions.
2 changes: 1 addition & 1 deletion lib/temporal/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def await_workflow_result(workflow, workflow_id:, run_id: nil, timeout: nil, nam
when 'WORKFLOW_EXECUTION_CANCELED'
raise Temporal::WorkflowCanceled
when 'WORKFLOW_EXECUTION_FAILED'
raise Temporal::Workflow::Errors.generate_error(closed_event.attributes.failure)
raise Temporal::Workflow::Errors.generate_error(closed_event.attributes.failure, config.converter)
when 'WORKFLOW_EXECUTION_CONTINUED_AS_NEW'
new_run_id = closed_event.attributes.new_execution_run_id
# Throw to let the caller know they're not getting the result
Expand Down
9 changes: 3 additions & 6 deletions lib/temporal/workflow/errors.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
require 'temporal/errors'
require 'temporal/concerns/payloads'

module Temporal
class Workflow
class Errors
extend Concerns::Payloads

# Convert a failure returned from the server to an Error to raise to the client
# failure: Temporal::Api::Failure::V1::Failure
def self.generate_error(failure, default_exception_class = StandardError)
def self.generate_error(failure, converter, default_exception_class = StandardError)
case failure.failure_info
when :application_failure_info
message = from_details_payloads(failure.application_failure_info.details)
message = converter.from_details_payloads(failure.application_failure_info.details)

exception_class = safe_constantize(failure.application_failure_info.type)
if exception_class.nil?
Expand Down Expand Up @@ -47,7 +44,7 @@ def self.generate_error(failure, default_exception_class = StandardError)
TimeoutError.new("Timeout type: #{failure.timeout_failure_info.timeout_type.to_s}")
when :canceled_failure_info
# TODO: Distinguish between different entity cancellations
StandardError.new(from_payloads(failure.canceled_failure_info.details))
StandardError.new(converter.from_payloads(failure.canceled_failure_info.details))
else
StandardError.new(failure.message)
end
Expand Down
13 changes: 8 additions & 5 deletions lib/temporal/workflow/state_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ def apply_event(event)

when 'ACTIVITY_TASK_FAILED'
state_machine.fail
dispatch(target, 'failed', Temporal::Workflow::Errors.generate_error(event.attributes.failure, ActivityException))
dispatch(target, 'failed', generate_error(event.attributes.failure, ActivityException))

when 'ACTIVITY_TASK_TIMED_OUT'
state_machine.time_out
dispatch(target, 'failed', Temporal::Workflow::Errors.generate_error(event.attributes.failure))
dispatch(target, 'failed', generate_error(event.attributes.failure))

when 'ACTIVITY_TASK_CANCEL_REQUESTED'
state_machine.requested
Expand Down Expand Up @@ -247,15 +247,15 @@ def apply_event(event)

when 'CHILD_WORKFLOW_EXECUTION_FAILED'
state_machine.fail
dispatch(target, 'failed', Temporal::Workflow::Errors.generate_error(event.attributes.failure))
dispatch(target, 'failed', generate_error(event.attributes.failure))

when 'CHILD_WORKFLOW_EXECUTION_CANCELED'
state_machine.cancel
dispatch(target, 'failed', Temporal::Workflow::Errors.generate_error(event.attributes.failure))
dispatch(target, 'failed', generate_error(event.attributes.failure))

when 'CHILD_WORKFLOW_EXECUTION_TIMED_OUT'
state_machine.time_out
dispatch(target, 'failed', Temporal::Workflow::Errors.generate_error(event.attributes.failure))
dispatch(target, 'failed', generate_error(event.attributes.failure))

when 'CHILD_WORKFLOW_EXECUTION_TERMINATED'
# todo
Expand Down Expand Up @@ -355,6 +355,9 @@ def track_release(release_name)
end
end

def generate_error(failure, default_exception_class = StandardError)
Temporal::Workflow::Errors.generate_error(failure, converter, default_exception_class)
end
end
end
end
8 changes: 3 additions & 5 deletions spec/fabricators/grpc/application_failure_fabricator.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
require 'temporal/concerns/payloads'
class TestDeserializer
include Temporal::Concerns::Payloads
end
require 'temporal/configuration'

# Simulates Temporal::Connection::Serializer::Failure
Fabricator(:api_application_failure, from: Temporal::Api::Failure::V1::Failure) do
transient :error_class, :backtrace
Expand All @@ -10,7 +8,7 @@ class TestDeserializer
application_failure_info do |attrs|
Temporal::Api::Failure::V1::ApplicationFailureInfo.new(
type: attrs[:error_class],
details: TestDeserializer.new.to_details_payloads(attrs[:message]),
details: Temporal::Configuration.new.converter.to_details_payloads(attrs[:message]),
)
end
end
7 changes: 2 additions & 5 deletions spec/fabricators/grpc/history_event_fabricator.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
require 'securerandom'

class TestSerializer
extend Temporal::Concerns::Payloads
end
require 'temporal/configuration'

Fabricator(:api_history_event, from: Temporal::Api::History::V1::HistoryEvent) do
event_id { 1 }
Expand Down Expand Up @@ -130,7 +127,7 @@ class TestSerializer
event_type { Temporal::Api::Enums::V1::EventType::EVENT_TYPE_ACTIVITY_TASK_CANCELED }
activity_task_canceled_event_attributes do |attrs|
Temporal::Api::History::V1::ActivityTaskCanceledEventAttributes.new(
details: TestSerializer.to_details_payloads('ACTIVITY_ID_NOT_STARTED'),
details: Temporal::Configuration.new.converter.to_details_payloads('ACTIVITY_ID_NOT_STARTED'),
scheduled_event_id: attrs[:event_id] - 2,
started_event_id: nil,
identity: 'test-worker@test-host'
Expand Down
10 changes: 6 additions & 4 deletions spec/unit/lib/temporal/workflow/errors_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ def initialize(message)
class SomeError < StandardError; end

describe Temporal::Workflow::Errors do
let(:config) { Temporal::Configuration.new }

describe '.generate_error' do
it "instantiates properly when the client has the error" do
message = "An error message"
Expand All @@ -27,7 +29,7 @@ class SomeError < StandardError; end
error_class: SomeError.to_s
)

e = Temporal::Workflow::Errors.generate_error(failure)
e = Temporal::Workflow::Errors.generate_error(failure, config.converter)
expect(e).to be_a(SomeError)
expect(e.message).to eq(message)
expect(e.backtrace).to eq(stack_trace)
Expand All @@ -46,7 +48,7 @@ class SomeError < StandardError; end
error_class: 'NonexistentError',
)

e = Temporal::Workflow::Errors.generate_error(failure)
e = Temporal::Workflow::Errors.generate_error(failure, config.converter)
expect(e).to be_a(StandardError)
expect(e.message).to eq("NonexistentError: An error message")
expect(e.backtrace).to eq(stack_trace)
Expand All @@ -72,7 +74,7 @@ class SomeError < StandardError; end
error_class: ErrorWithTwoArgs.to_s,
)

e = Temporal::Workflow::Errors.generate_error(failure)
e = Temporal::Workflow::Errors.generate_error(failure, config.converter)
expect(e).to be_a(StandardError)
expect(e.message).to eq("ErrorWithTwoArgs: An error message")
expect(e.backtrace).to eq(stack_trace)
Expand Down Expand Up @@ -100,7 +102,7 @@ class SomeError < StandardError; end
error_class: ErrorThatRaisesInInitialize.to_s,
)

e = Temporal::Workflow::Errors.generate_error(failure)
e = Temporal::Workflow::Errors.generate_error(failure, config.converter)
expect(e).to be_a(StandardError)
expect(e.message).to eq("ErrorThatRaisesInInitialize: An error message")
expect(e.backtrace).to eq(stack_trace)
Expand Down

0 comments on commit 78a9250

Please sign in to comment.