@@ -501,6 +501,33 @@ async def test_schedule_activity_on_first_replay(self, mock_client: AsyncMock) -
501501 assert commands [0 ]["arguments" ]["codec" ] == "json"
502502 assert serializer .decode (commands [0 ]["arguments" ]["blob" ], codec = "json" ) == ["hello" ]
503503
504+ @pytest .mark .asyncio
505+ async def test_workflow_task_completion_error_fails_task_for_fast_redispatch (
506+ self , mock_client : AsyncMock
507+ ) -> None :
508+ mock_client .complete_workflow_task .side_effect = TimeoutError ("completion timed out" )
509+ worker = Worker (mock_client , task_queue = "q1" , workflows = [TestWorkflow ], activities = [])
510+ task = {
511+ "task_id" : "t-complete-timeout" ,
512+ "workflow_type" : "test-wf" ,
513+ "workflow_task_attempt" : 2 ,
514+ "history_events" : [],
515+ "arguments" : '["hello"]' ,
516+ "payload_codec" : "json" ,
517+ }
518+
519+ result = await worker ._run_workflow_task (task )
520+
521+ assert result is None
522+ mock_client .complete_workflow_task .assert_awaited_once ()
523+ mock_client .fail_workflow_task .assert_awaited_once ()
524+ call_kwargs = mock_client .fail_workflow_task .await_args .kwargs
525+ assert call_kwargs ["task_id" ] == "t-complete-timeout"
526+ assert call_kwargs ["workflow_task_attempt" ] == 2
527+ assert call_kwargs ["lease_owner" ] == worker .worker_id
528+ assert call_kwargs ["failure_type" ] == "TimeoutError"
529+ assert "completion timed out" in call_kwargs ["message" ]
530+
504531 @pytest .mark .asyncio
505532 async def test_workflow_command_payload_warning_uses_client_policy (
506533 self , mock_client : AsyncMock , caplog : pytest .LogCaptureFixture
@@ -673,6 +700,44 @@ async def test_update_backed_workflow_task_completes_update_command(
673700 ]
674701 mock_client .fail_workflow_task .assert_not_called ()
675702
703+ @pytest .mark .asyncio
704+ async def test_update_task_completion_error_fails_task_for_fast_redispatch (
705+ self , mock_client : AsyncMock
706+ ) -> None :
707+ mock_client .complete_workflow_task .side_effect = TimeoutError ("update completion timed out" )
708+ worker = Worker (mock_client , task_queue = "q1" , workflows = [UpdateWorkflow ], activities = [])
709+ task = {
710+ "task_id" : "t-update-timeout" ,
711+ "workflow_type" : "update-wf" ,
712+ "workflow_task_attempt" : 3 ,
713+ "workflow_update_id" : "upd-worker-1" ,
714+ "workflow_wait_kind" : "update" ,
715+ "history_events" : [
716+ {
717+ "event_type" : "UpdateAccepted" ,
718+ "payload" : {
719+ "update_id" : "upd-worker-1" ,
720+ "update_name" : "increment" ,
721+ "arguments" : serializer .encode ([6 ], codec = "json" ),
722+ "payload_codec" : "json" ,
723+ },
724+ },
725+ ],
726+ "arguments" : "[]" ,
727+ "payload_codec" : "json" ,
728+ }
729+
730+ result = await worker ._run_workflow_task (task )
731+
732+ assert result is None
733+ mock_client .complete_workflow_task .assert_awaited_once ()
734+ mock_client .fail_workflow_task .assert_awaited_once ()
735+ call_kwargs = mock_client .fail_workflow_task .await_args .kwargs
736+ assert call_kwargs ["task_id" ] == "t-update-timeout"
737+ assert call_kwargs ["workflow_task_attempt" ] == 3
738+ assert call_kwargs ["failure_type" ] == "TimeoutError"
739+ assert "update completion timed out" in call_kwargs ["message" ]
740+
676741 @pytest .mark .asyncio
677742 async def test_query_task_executes_registered_query (self , mock_client : AsyncMock ) -> None :
678743 worker = Worker (mock_client , task_queue = "q1" , workflows = [QueryWorkflow ], activities = [])
0 commit comments