From 41d13a7633efccdc193f833b884fd5c63459873b Mon Sep 17 00:00:00 2001 From: GSmithApps Date: Thu, 2 Jan 2025 16:03:35 -0600 Subject: [PATCH 01/10] docs: added notes to `ApplicationError` and `FailureError` exception docstrings. --- temporalio/exceptions.py | 54 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 95776623..62875251 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -1,4 +1,23 @@ -"""Common Temporal exceptions.""" +""" +Common Temporal exceptions. + +# Temporal Failure + +Most Temporal SDKs have a base class that the other Failures extend. +In python, it is the ``FailureError``. + +# Application Failure + +Workflow, and Activity, and Nexus Operation code use Application Failures to +communicate application-specific failures that happen. +This is the only type of Temporal Failure created and thrown by user code. +In the Python SDK, it is the ``ApplicationError``. + +# References + +More information can be found in the docs at +https://docs.temporal.io/references/failures#workflow-execution-failures. +""" import asyncio from datetime import timedelta @@ -23,7 +42,16 @@ def cause(self) -> Optional[BaseException]: class FailureError(TemporalError): - """Base for runtime failures during workflow/activity execution.""" + """ + Base for runtime failures during workflow/activity execution. + + This is extended by ``ApplicationError``, which can be raised in a Workflow to fail the Workflow Execution. + Workflow Execution Failures put the Workflow Execution into the "Failed" state and no more attempts will + be made in progressing this execution. + + Any exception that does not extend this exception + is considered a Workflow Task Failure. These types of failures will cause the Workflow Task to be retried. + """ def __init__( self, @@ -71,7 +99,27 @@ def __init__( class ApplicationError(FailureError): - """Error raised during workflow/activity execution.""" + """ + Error raised during workflow/activity execution. + + Can be raised in a Workflow to fail the Workflow Execution. + Workflow Execution Failures put the Workflow Execution into the "Failed" state and no more attempts will + be made in progressing their execution. + + If you are creating custom exceptions or raising typical Python-based + exceptions you would either need to extend this class or + explicitly state that the exception is a Workflow Execution Failure by raising a new ``ApplicationError``. + + Any exception that does not extend this exception + is considered a Workflow Task Failure. These types of failures will cause the Workflow Task to be retried. + + # Example + + >>> from temporalio.exceptions import ApplicationError + ... # ... + ... if isDelivery and distance.get_kilometers() > 25: + ... raise ApplicationError("Customer lives outside the service area") + """ def __init__( self, From 5672e5c131b7a14423ea390cd4a28f0cfefb6476 Mon Sep 17 00:00:00 2001 From: GSmithApps Date: Thu, 2 Jan 2025 17:03:04 -0600 Subject: [PATCH 02/10] fix for linter --- temporalio/exceptions.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 62875251..5cc5c0b2 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -1,5 +1,4 @@ -""" -Common Temporal exceptions. +"""Common Temporal exceptions. # Temporal Failure @@ -42,8 +41,7 @@ def cause(self) -> Optional[BaseException]: class FailureError(TemporalError): - """ - Base for runtime failures during workflow/activity execution. + """Base for runtime failures during workflow/activity execution. This is extended by ``ApplicationError``, which can be raised in a Workflow to fail the Workflow Execution. Workflow Execution Failures put the Workflow Execution into the "Failed" state and no more attempts will @@ -99,8 +97,7 @@ def __init__( class ApplicationError(FailureError): - """ - Error raised during workflow/activity execution. + """Error raised during workflow/activity execution. Can be raised in a Workflow to fail the Workflow Execution. Workflow Execution Failures put the Workflow Execution into the "Failed" state and no more attempts will From f40030bfce21dd4a78f693bd3330cac13c394757 Mon Sep 17 00:00:00 2001 From: Grant <14.gsmith.14@gmail.com> Date: Mon, 6 Jan 2025 15:27:53 -0600 Subject: [PATCH 03/10] Update Docstring of FailureError Co-authored-by: Dan Davison --- temporalio/exceptions.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 5cc5c0b2..32b2f6c7 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -41,14 +41,16 @@ def cause(self) -> Optional[BaseException]: class FailureError(TemporalError): - """Base for runtime failures during workflow/activity execution. + """Base class for exceptions that cause a workflow execution failure. + + Do not raise this directly in workflow code: raise a child exception such as `ApplicationError` instead. - This is extended by ``ApplicationError``, which can be raised in a Workflow to fail the Workflow Execution. - Workflow Execution Failures put the Workflow Execution into the "Failed" state and no more attempts will - be made in progressing this execution. + Workflow execution failure puts the workflow execution into "Failed" state, and no further attempts will + be made to progress the workflow execution. - Any exception that does not extend this exception - is considered a Workflow Task Failure. These types of failures will cause the Workflow Task to be retried. + By default, any exception that does not extend this class causes the Workflow Task to be retried, rather than failing the workflow execution. + + The default behavior can be changed by providing a list of exception types to ``workflow_failure_exception_types`` when creating a worker or ``failure_exception_types`` on the ``@workflow.defn`` decorator. """ def __init__( From cd244ffbf797a5bdfecf5a8596327d368f512e09 Mon Sep 17 00:00:00 2001 From: Grant <14.gsmith.14@gmail.com> Date: Mon, 6 Jan 2025 15:28:50 -0600 Subject: [PATCH 04/10] Update docstring for `ApplicationError` Co-authored-by: Dan Davison --- temporalio/exceptions.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 32b2f6c7..acf42e49 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -99,18 +99,10 @@ def __init__( class ApplicationError(FailureError): - """Error raised during workflow/activity execution. + """Error raised during workflow/activity execution to cause a workflow execution failure. - Can be raised in a Workflow to fail the Workflow Execution. - Workflow Execution Failures put the Workflow Execution into the "Failed" state and no more attempts will - be made in progressing their execution. - - If you are creating custom exceptions or raising typical Python-based - exceptions you would either need to extend this class or - explicitly state that the exception is a Workflow Execution Failure by raising a new ``ApplicationError``. - - Any exception that does not extend this exception - is considered a Workflow Task Failure. These types of failures will cause the Workflow Task to be retried. + Workflow Execution Failures put the Workflow Execution into the "Failed" state and no further attempt will + be made to progress their execution. # Example From 98ae6f8ddaad8bd737c1bc1feb7e58559d294599 Mon Sep 17 00:00:00 2001 From: GSmithApps Date: Mon, 6 Jan 2025 16:05:06 -0600 Subject: [PATCH 05/10] docs: fix for linter --- temporalio/exceptions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index acf42e49..be9e49c1 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -42,15 +42,15 @@ def cause(self) -> Optional[BaseException]: class FailureError(TemporalError): """Base class for exceptions that cause a workflow execution failure. - + Do not raise this directly in workflow code: raise a child exception such as `ApplicationError` instead. Workflow execution failure puts the workflow execution into "Failed" state, and no further attempts will be made to progress the workflow execution. By default, any exception that does not extend this class causes the Workflow Task to be retried, rather than failing the workflow execution. - - The default behavior can be changed by providing a list of exception types to ``workflow_failure_exception_types`` when creating a worker or ``failure_exception_types`` on the ``@workflow.defn`` decorator. + + The default behavior can be changed by providing a list of exception types to ``workflow_failure_exception_types`` when creating a worker or ``failure_exception_types`` on the ``@workflow.defn`` decorator. """ def __init__( From eedc6c3f5f715a5d8b83ec5316845e1a4cbca100 Mon Sep 17 00:00:00 2001 From: GSmithApps Date: Fri, 14 Feb 2025 23:50:40 -0600 Subject: [PATCH 06/10] small clarification to exception docstring --- temporalio/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index be9e49c1..1bc54724 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -43,7 +43,7 @@ def cause(self) -> Optional[BaseException]: class FailureError(TemporalError): """Base class for exceptions that cause a workflow execution failure. - Do not raise this directly in workflow code: raise a child exception such as `ApplicationError` instead. + Do not raise this directly in workflow code: raise `ApplicationError` instead (which inherits from this `FailureError`). Workflow execution failure puts the workflow execution into "Failed" state, and no further attempts will be made to progress the workflow execution. From fbfabe166ad23472da6e90d9700868502c63cfe4 Mon Sep 17 00:00:00 2001 From: Grant <14.gsmith.14@gmail.com> Date: Sat, 15 Feb 2025 08:52:51 -0600 Subject: [PATCH 07/10] Update temporalio/exceptions.py Co-authored-by: Dan Davison --- temporalio/exceptions.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 1bc54724..72ab3fb9 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -43,14 +43,16 @@ def cause(self) -> Optional[BaseException]: class FailureError(TemporalError): """Base class for exceptions that cause a workflow execution failure. - Do not raise this directly in workflow code: raise `ApplicationError` instead (which inherits from this `FailureError`). + Do not raise this directly: raise ``ApplicationError`` instead. - Workflow execution failure puts the workflow execution into "Failed" state, and no further attempts will - be made to progress the workflow execution. + Workflow execution failure puts the workflow execution into "Failed" state, + and no further attempts will be made to progress the workflow execution. - By default, any exception that does not extend this class causes the Workflow Task to be retried, rather than failing the workflow execution. - - The default behavior can be changed by providing a list of exception types to ``workflow_failure_exception_types`` when creating a worker or ``failure_exception_types`` on the ``@workflow.defn`` decorator. + By default, any exception that does not inherit from this class causes the + workflow task to be retried, rather than failing the workflow execution. The + default behavior can be changed by providing a list of exception types to + ``workflow_failure_exception_types`` when creating a worker or + ``failure_exception_types`` on the ``@workflow.defn`` decorator. """ def __init__( From 44416b09017ce265bf29ea1c2388f802b5c36056 Mon Sep 17 00:00:00 2001 From: Grant <14.gsmith.14@gmail.com> Date: Sat, 15 Feb 2025 08:53:05 -0600 Subject: [PATCH 08/10] Update temporalio/exceptions.py Co-authored-by: Dan Davison --- temporalio/exceptions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 72ab3fb9..e91851b5 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -101,17 +101,17 @@ def __init__( class ApplicationError(FailureError): - """Error raised during workflow/activity execution to cause a workflow execution failure. + """Raised in workflow/activity code to cause a workflow execution failure. - Workflow Execution Failures put the Workflow Execution into the "Failed" state and no further attempt will - be made to progress their execution. + Workflow execution failure puts the workflow execution into "Failed" state, + and no further attempts will be made to progress the workflow execution. - # Example + .. code-block:: python - >>> from temporalio.exceptions import ApplicationError - ... # ... - ... if isDelivery and distance.get_kilometers() > 25: - ... raise ApplicationError("Customer lives outside the service area") + from temporalio.exceptions import ApplicationError + # ... + if is_delivery and distance.get_kilometers() > 25: + raise ApplicationError("Customer lives outside the service area") """ def __init__( From 89f9b02125f162a1bc403e169d0a044bb09c3b98 Mon Sep 17 00:00:00 2001 From: Grant <14.gsmith.14@gmail.com> Date: Sat, 15 Feb 2025 09:04:42 -0600 Subject: [PATCH 09/10] Update exceptions.py based on code review --- temporalio/exceptions.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index e91851b5..9fa2ae4d 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -11,11 +11,6 @@ communicate application-specific failures that happen. This is the only type of Temporal Failure created and thrown by user code. In the Python SDK, it is the ``ApplicationError``. - -# References - -More information can be found in the docs at -https://docs.temporal.io/references/failures#workflow-execution-failures. """ import asyncio From ac38f6b95dbe84ccb71499207bd1edb73443e046 Mon Sep 17 00:00:00 2001 From: Grant <14.gsmith.14@gmail.com> Date: Sat, 15 Feb 2025 09:17:47 -0600 Subject: [PATCH 10/10] Update exceptions.py --- temporalio/exceptions.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 9fa2ae4d..0ba1870f 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -1,17 +1,4 @@ -"""Common Temporal exceptions. - -# Temporal Failure - -Most Temporal SDKs have a base class that the other Failures extend. -In python, it is the ``FailureError``. - -# Application Failure - -Workflow, and Activity, and Nexus Operation code use Application Failures to -communicate application-specific failures that happen. -This is the only type of Temporal Failure created and thrown by user code. -In the Python SDK, it is the ``ApplicationError``. -""" +"""Common Temporal exceptions.""" import asyncio from datetime import timedelta