@@ -91,7 +91,8 @@ def _build_http_management_payload(
9191 http_base_url : str ,
9292 required_query_string_parameters : str ,
9393 use_forwarded_host : bool ,
94- request : func .HttpRequest | None ) -> HttpManagementPayload :
94+ request : func .HttpRequest | None ,
95+ return_internal_server_error_on_failure : bool = False ) -> HttpManagementPayload :
9596 encoded_instance_id = quote (instance_id , safe = "" )
9697 configured_base_url = http_base_url or base_url
9798 request_origin : str | None = None
@@ -113,7 +114,9 @@ def _build_http_management_payload(
113114 instance_status_url ,
114115 required_query_string_parameters ,
115116 management_urls = management_urls ,
116- request_origin = request_origin )
117+ request_origin = request_origin ,
118+ return_internal_server_error_on_failure = (
119+ return_internal_server_error_on_failure ))
117120
118121
119122# Client class used for Durable Functions
@@ -247,14 +250,24 @@ def _parse_client_configuration(self, client_as_string: str) -> None:
247250 # TODO: convert the string value back to timedelta - annoying regex?
248251 self .grpcHttpClientTimeout = client .get ("grpcHttpClientTimeout" ) or timedelta (seconds = 30 )
249252
250- def create_check_status_response (self , request : func .HttpRequest , instance_id : str ) -> func .HttpResponse :
253+ def create_check_status_response (
254+ self ,
255+ request : func .HttpRequest ,
256+ instance_id : str ,
257+ return_internal_server_error_on_failure : bool = False
258+ ) -> func .HttpResponse :
251259 """Creates an HTTP response for checking the status of a Durable Function instance.
252260
253261 Args:
254262 request (func.HttpRequest): The incoming HTTP request.
255263 instance_id (str): The ID of the Durable Function instance.
264+ return_internal_server_error_on_failure (bool): Whether status
265+ queries should return HTTP 500 for failed orchestrations.
256266 """
257- payload = self ._get_client_response_links (request , instance_id )
267+ payload = self ._get_client_response_links (
268+ request ,
269+ instance_id ,
270+ return_internal_server_error_on_failure )
258271 return func .HttpResponse (
259272 body = str (payload ),
260273 status_code = 202 ,
@@ -264,13 +277,16 @@ def create_check_status_response(self, request: func.HttpRequest, instance_id: s
264277 # the required query string (webhook key / task hub / connection)
265278 # so a client that follows the header is authorized.
266279 'Location' : payload ['statusQueryGetUri' ],
280+ 'Retry-After' : '10' ,
267281 },
268282 )
269283
270284 def create_http_management_payload (
271285 self ,
272286 request : func .HttpRequest | str | None = None ,
273- instance_id : str | None = None ) -> HttpManagementPayload :
287+ instance_id : str | None = None ,
288+ return_internal_server_error_on_failure : bool = False
289+ ) -> HttpManagementPayload :
274290 """Creates an HTTP management payload for a Durable Function instance.
275291
276292 Two call styles are supported:
@@ -286,6 +302,8 @@ def create_http_management_payload(
286302 for backwards compatibility, the instance ID when called with a
287303 single positional argument.
288304 instance_id (str | None): The ID of the Durable Function instance.
305+ return_internal_server_error_on_failure (bool): Whether the status
306+ query should return HTTP 500 for failed orchestrations.
289307 """
290308 # Backwards-compatibility: v1 accepted a single positional ``instance_id``.
291309 if instance_id is None and isinstance (request , str ):
@@ -294,17 +312,26 @@ def create_http_management_payload(
294312 if instance_id is None :
295313 raise TypeError ("instance_id is required" )
296314 resolved_request = request if isinstance (request , func .HttpRequest ) else None
297- return self ._get_client_response_links (resolved_request , instance_id )
315+ return self ._get_client_response_links (
316+ resolved_request ,
317+ instance_id ,
318+ return_internal_server_error_on_failure )
298319
299- def _get_client_response_links (self , request : func .HttpRequest | None , instance_id : str ) -> HttpManagementPayload :
320+ def _get_client_response_links (
321+ self ,
322+ request : func .HttpRequest | None ,
323+ instance_id : str ,
324+ return_internal_server_error_on_failure : bool = False
325+ ) -> HttpManagementPayload :
300326 return _build_http_management_payload (
301327 instance_id ,
302328 self .managementUrls ,
303329 self .baseUrl ,
304330 self .httpBaseUrl ,
305331 self .requiredQueryStringParameters ,
306332 self .useForwardedHost ,
307- request )
333+ request ,
334+ return_internal_server_error_on_failure )
308335
309336 # ------------------------------------------------------------------
310337 # Backwards-compatibility shims for the v1 azure-functions-durable
@@ -521,7 +548,9 @@ async def wait_for_completion_or_create_check_status_response(
521548 request : func .HttpRequest ,
522549 instance_id : str ,
523550 timeout_in_milliseconds : int = 10000 ,
524- retry_interval_in_milliseconds : int = 1000 ) -> func .HttpResponse :
551+ retry_interval_in_milliseconds : int = 1000 ,
552+ return_internal_server_error_on_failure : bool = False
553+ ) -> func .HttpResponse :
525554 """Wait for an orchestration to complete, or return a check-status response.
526555
527556 If the orchestration completes within the timeout, an HTTP response
@@ -530,6 +559,9 @@ async def wait_for_completion_or_create_check_status_response(
530559
531560 The ``retry_interval_in_milliseconds`` argument has no durabletask
532561 equivalent (durabletask waits server-side) and is ignored.
562+
563+ When ``return_internal_server_error_on_failure`` is true, failed
564+ orchestrations return HTTP 500 instead of HTTP 200.
533565 """
534566 if retry_interval_in_milliseconds > timeout_in_milliseconds :
535567 raise Exception (
@@ -540,10 +572,16 @@ async def wait_for_completion_or_create_check_status_response(
540572 state = await self .wait_for_orchestration_completion (
541573 instance_id , timeout = timeout_in_milliseconds / 1000 )
542574 except TimeoutError :
543- return self .create_check_status_response (request , instance_id )
575+ return self .create_check_status_response (
576+ request ,
577+ instance_id ,
578+ return_internal_server_error_on_failure )
544579
545580 if state is None :
546- return self .create_check_status_response (request , instance_id )
581+ return self .create_check_status_response (
582+ request ,
583+ instance_id ,
584+ return_internal_server_error_on_failure )
547585
548586 if state .runtime_status == OrchestrationStatus .COMPLETED :
549587 return self ._create_http_response (200 , state .serialized_output )
@@ -552,8 +590,12 @@ async def wait_for_completion_or_create_check_status_response(
552590 200 , DurableOrchestrationStatus .from_orchestration_state (state ).to_json ())
553591 if state .runtime_status == OrchestrationStatus .FAILED :
554592 return self ._create_http_response (
555- 500 , DurableOrchestrationStatus .from_orchestration_state (state ).to_json ())
556- return self .create_check_status_response (request , instance_id )
593+ 500 if return_internal_server_error_on_failure else 200 ,
594+ DurableOrchestrationStatus .from_orchestration_state (state ).to_json ())
595+ return self .create_check_status_response (
596+ request ,
597+ instance_id ,
598+ return_internal_server_error_on_failure )
557599
558600 @deprecated ("rewind is deprecated; use rewind_orchestration instead." )
559601 async def rewind (
@@ -649,40 +691,57 @@ def _parse_client_configuration(self, client_as_string: str) -> None:
649691 "grpcHttpClientTimeout" ) or timedelta (seconds = 30 )
650692
651693 def create_check_status_response (
652- self , request : func .HttpRequest , instance_id : str ) -> func .HttpResponse :
653- payload = self ._get_client_response_links (request , instance_id )
694+ self ,
695+ request : func .HttpRequest ,
696+ instance_id : str ,
697+ return_internal_server_error_on_failure : bool = False
698+ ) -> func .HttpResponse :
699+ payload = self ._get_client_response_links (
700+ request ,
701+ instance_id ,
702+ return_internal_server_error_on_failure )
654703 return func .HttpResponse (
655704 body = str (payload ),
656705 status_code = 202 ,
657706 headers = {
658707 "content-type" : "application/json" ,
659708 "Location" : payload ["statusQueryGetUri" ],
709+ "Retry-After" : "10" ,
660710 },
661711 )
662712
663713 def create_http_management_payload (
664714 self ,
665715 request : func .HttpRequest | str | None = None ,
666- instance_id : str | None = None ) -> HttpManagementPayload :
716+ instance_id : str | None = None ,
717+ return_internal_server_error_on_failure : bool = False
718+ ) -> HttpManagementPayload :
667719 if instance_id is None and isinstance (request , str ):
668720 instance_id = request
669721 request = None
670722 if instance_id is None :
671723 raise TypeError ("instance_id is required" )
672724 resolved_request = request if isinstance (request , func .HttpRequest ) else None
673- return self ._get_client_response_links (resolved_request , instance_id )
725+ return self ._get_client_response_links (
726+ resolved_request ,
727+ instance_id ,
728+ return_internal_server_error_on_failure )
674729
675730 def _get_client_response_links (
676- self , request : func .HttpRequest | None ,
677- instance_id : str ) -> HttpManagementPayload :
731+ self ,
732+ request : func .HttpRequest | None ,
733+ instance_id : str ,
734+ return_internal_server_error_on_failure : bool = False
735+ ) -> HttpManagementPayload :
678736 return _build_http_management_payload (
679737 instance_id ,
680738 self .managementUrls ,
681739 self .baseUrl ,
682740 self .httpBaseUrl ,
683741 self .requiredQueryStringParameters ,
684742 self .useForwardedHost ,
685- request )
743+ request ,
744+ return_internal_server_error_on_failure )
686745
687746
688747def _close_cached_sync_clients () -> None :
0 commit comments