Skip to content

Do not fail workflow task if an error occurs when marking it as completed #210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/temporal/workflow/task_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,19 @@ def complete_task(commands, query_results)
binary_checksum: binary_checksum,
query_results: query_results
)
rescue StandardError => error
# We rescue the error here to avoid failing the task in the process
# function above. One common cause of errors here is if the current
# workflow task is invalidated by a concurrent signal arriving while it
# tries to complete the workflow. In this case we do not need to and
# should not fail the workflow task.
#
# Not failing the workflow task will still result it being retried after
# a delay which is the behavior we'd want in cases like the above but
# also for ephemeral issues like network outages.
Temporal.logger.error("Unable to complete the workflow task", metadata.to_h.merge(error: error.inspect))

Temporal::ErrorHandler.handle(error, config, metadata: metadata)
end

def complete_query(result)
Expand Down
27 changes: 27 additions & 0 deletions spec/unit/lib/temporal/workflow/task_processor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,33 @@
end
end

context 'when recording the workflow task complete fails' do
let(:exception) { GRPC::InvalidArgument.new('workflow task could not be completed') }

before { allow(connection).to receive(:respond_workflow_task_completed).and_raise(exception) }

it 'does not try to fail the workflow task' do
subject.process

expect(connection).to_not have_received(:respond_workflow_task_failed)
end

it 'calls error_handlers' do
reported_error = nil
reported_metadata = nil

config.on_error do |error, metadata: nil|
reported_error = error
reported_metadata = metadata
end

subject.process

expect(reported_error).to be_an_instance_of(GRPC::InvalidArgument)
expect(reported_metadata).to be_an_instance_of(Temporal::Metadata::WorkflowTask)
end
end

context 'when workflow task raises an exception' do
let(:exception) { StandardError.new('workflow task failed') }

Expand Down