@@ -546,6 +546,34 @@ def throw_activity_with_retry(ctx: task.ActivityContext, _):
546546 assert throw_activity_counter == 9
547547 assert child_orch_counter == 3
548548
549+ # Test 2: Verify NonRetryableError prevents retries even with retry policy
550+ non_retryable_counter = 0
551+
552+ def throw_non_retryable (ctx : task .ActivityContext , _ ):
553+ nonlocal non_retryable_counter
554+ non_retryable_counter += 1
555+ raise task .NonRetryableError ("Cannot retry this!" )
556+
557+ def orchestrator_with_non_retryable (ctx : task .OrchestrationContext , _ ):
558+ # Even with retry policy, NonRetryableError should fail immediately
559+ yield ctx .call_activity (throw_non_retryable , retry_policy = retry_policy )
560+
561+ with worker .TaskHubGrpcWorker () as w :
562+ w .add_orchestrator (orchestrator_with_non_retryable )
563+ w .add_activity (throw_non_retryable )
564+ w .start ()
565+ w .wait_for_ready (timeout = 10 )
566+
567+ task_hub_client = client .TaskHubGrpcClient ()
568+ id = task_hub_client .schedule_new_orchestration (orchestrator_with_non_retryable )
569+ state = task_hub_client .wait_for_orchestration_completion (id , timeout = 30 )
570+ assert state is not None
571+ assert state .runtime_status == client .OrchestrationStatus .FAILED
572+ assert state .failure_details is not None
573+ assert "Cannot retry this!" in state .failure_details .message
574+ # Key assertion: activity was called exactly once (no retries)
575+ assert non_retryable_counter == 1
576+
549577
550578def test_retry_timeout ():
551579 # This test verifies that the retry timeout is working as expected.
0 commit comments