Skip to content

Commit 937482e

Browse files
Converted AlreadyStarted error handling to use rpc status
1 parent fd445bd commit 937482e

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

Diff for: lib/temporal/connection/grpc.rb

+8-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
require 'temporal/connection/serializer'
66
require 'temporal/connection/serializer/failure'
77
require 'gen/temporal/api/workflowservice/v1/service_services_pb'
8+
require 'gen/temporal/api/errordetails/v1/message_pb'
89
require 'temporal/concerns/payloads'
910

1011
module Temporal
@@ -117,9 +118,13 @@ def start_workflow_execution(
117118

118119
client.start_workflow_execution(request)
119120
rescue ::GRPC::AlreadyExists => e
120-
# Feel like there should be cleaner way to do this...
121-
run_id = e.details[/RunId: ([a-f0-9]+-[a-f0-9]+-[a-f0-9]+-[a-f0-9]+-[a-f0-9]+)/, 1]
122-
raise Temporal::WorkflowExecutionAlreadyStartedFailure.new(e.details, run_id)
121+
cast_error = e.to_rpc_status&.details&.map do |any_error|
122+
next unless any_error.type_url == 'type.googleapis.com/temporal.api.errordetails.v1.WorkflowExecutionAlreadyStartedFailure'
123+
124+
any_error.unpack(Temporal::Api::ErrorDetails::V1::WorkflowExecutionAlreadyStartedFailure)
125+
end&.compact&.first
126+
127+
raise Temporal::WorkflowExecutionAlreadyStartedFailure.new(e.details, cast_error&.run_id)
123128
end
124129

125130
SERVER_MAX_GET_WORKFLOW_EXECUTION_HISTORY_POLL = 30

Diff for: spec/spec_helper.rb

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
require 'temporal'
1818
require 'google/protobuf/well_known_types'
19+
require 'google/rpc/status_pb'
1920
require 'pry'
2021

2122
Dir[File.expand_path('config/*.rb', __dir__)].sort.each { |f| require f }

Diff for: spec/unit/lib/temporal/grpc_client_spec.rb

+18-10
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,28 @@
44
let(:namespace) { 'test-namespace' }
55
let(:workflow_id) { SecureRandom.uuid }
66
let(:run_id) { SecureRandom.uuid }
7-
let(:now) { Time.now}
7+
let(:now) { Time.now.utc }
8+
let(:already_started_error) do
9+
detail_error = Google::Protobuf::Any.new.tap do |any|
10+
any.pack(Temporal::Api::ErrorDetails::V1::WorkflowExecutionAlreadyStartedFailure.new(start_request_id: SecureRandom.uuid, run_id: run_id))
11+
end
12+
rpc_status = Google::Rpc::Status.new(
13+
code: 6,
14+
message: 'Workflow execution already finished successfully. WorkflowId: TestWorkflow-1, RunId: baaf1d86-4459-4ecd-a288-47aeae55245d. Workflow Id reuse policy: allow duplicate workflow Id if last run failed.',
15+
details: [detail_error],
16+
)
17+
GRPC::AlreadyExists.new('details', { 'grpc-status-details-bin' => Google::Rpc::Status.encode(rpc_status) })
18+
end
819

920
before do
1021
allow(subject).to receive(:client).and_return(grpc_stub)
11-
22+
1223
allow(Time).to receive(:now).and_return(now)
1324
end
1425

1526
describe '#start_workflow_execution' do
1627
it 'provides the existing run_id when the workflow is already started' do
17-
allow(grpc_stub).to receive(:start_workflow_execution).and_raise(
18-
GRPC::AlreadyExists,
19-
'Workflow execution already finished successfully. WorkflowId: TestWorkflow-1, RunId: baaf1d86-4459-4ecd-a288-47aeae55245d. Workflow Id reuse policy: allow duplicate workflow Id if last run failed.'
20-
)
28+
allow(grpc_stub).to receive(:start_workflow_execution).and_raise(already_started_error)
2129

2230
expect do
2331
subject.start_workflow_execution(
@@ -31,11 +39,11 @@
3139
memo: {}
3240
)
3341
end.to raise_error(Temporal::WorkflowExecutionAlreadyStartedFailure) do |e|
34-
expect(e.run_id).to eql('baaf1d86-4459-4ecd-a288-47aeae55245d')
42+
expect(e.run_id).to eql(run_id)
3543
end
3644
end
3745
end
38-
46+
3947
describe '#signal_with_start_workflow' do
4048
let(:temporal_response) do
4149
Temporal::Api::WorkflowService::V1::SignalWithStartWorkflowExecutionResponse.new(run_id: 'xxx')
@@ -148,7 +156,7 @@
148156
end
149157
end
150158

151-
it 'demands a timeout to be specified' do
159+
it 'demands a timeout to be specified' do
152160
expect do
153161
subject.get_workflow_execution_history(
154162
namespace: namespace,
@@ -161,7 +169,7 @@
161169
end
162170
end
163171

164-
it 'disallows a timeout larger than the server timeout' do
172+
it 'disallows a timeout larger than the server timeout' do
165173
expect do
166174
subject.get_workflow_execution_history(
167175
namespace: namespace,

0 commit comments

Comments
 (0)