New in 0.16.2

v0.16.3

Workflow

Errors

Handling errors in a distributed system is typically complex. Infinitic simplifies this by automatically tracking error chains and allowing you to handle errors directly within the workflow.

Error when processing a task

Tasks are processed within workers. If an exception occurs while processing a task, it is caught by the worker, and the task is automatically retried according to the retry policy.

Error when processing a task

If all retries fail, the worker notifies the workflow of the task failure with a WorkerException. This exception includes the following properties:

PropertyTypeDescription
workerNameStringName of the worker where the exception occured
nameStringException name
messageStringException message
stackTraceToStringStringString representation of the exception stack trace
causeWorkerException(optional) Cause of the exception

Serializing exceptions can be error-prone. Therefore, we "normalize" them into a WorkerException format.

What happens next in the workflow depends on whether it is waiting for the task to complete:

If the workflow expects the task result

This situation occurs when a task is dispatched synchronously or when awaiting the result of a Deferred<T>. Here, a TaskFailedException is thrown within the workflow, containing these properties:

PropertyTypeDescription
taskNameStringTask name
taskIdStringTask id
methodNameStringMethod called
workerExceptionWorkerExceptionCause of task failure

Error when processing a sync task

If the client expects this workflow's result, it will encounter a WorkflowFailedException:

Error when processing a sync task

Additionally, if another workflow expects this workflow's result, it will also encounter a WorkflowFailedException:

Error when processing a sync task

The WorkflowFailedException includes these properties:

PropertyTypeDescription
workflowNameStringWorkflow name
workflowIdStringWorkflow id
methodNameStringMethod called
methodRunIdStringMethod run id
deferredExceptionDeferredExceptionCause of workflow failure

In the example above, deferredException would be a TaskFailedException.

If the workflow does not expect the task result

This occurs when a task is dispatched asynchronously or is part of a method running in parallel.

Error when processing an async task

In this case, the task fails, but the workflow continues without error, as the failed task is not on the main execution path. If the workflow later waits for the result, a TaskFailedException will be thrown at that time:

Error when processing an async task

Errors due to cancellation and more

Failures of synchronous tasks result in TaskFailedException, while failures of synchronous child workflows result in WorkflowFailedException. Similar errors arise from cancellation and other scenarios:

NameWhen it happens
TaskFailedExceptionThe task has failed after all planned retries have failed.
TaskCanceledExceptionThe task has been canceled.
WorkflowFailedExceptionThe targeted workflow has a failed synchronous task or child workflow
WorkflowCanceledExceptionThe targeted workflow has been canceled.
WorkflowUnknownExceptionThe targeted workflow never existed or is already completed or canceled. This can occur when dispatching a method on a stub created by getWorkflowById.
WorkflowTaskFailedExceptionAn error occurred directly within the workflow code.

All these exceptions inherit from io.infinitic.exceptions.DeferredException

Try/catch in workflows

Use try/catch of DeferredException in workflows to ensure that the workflow continues even in case of Service failure (i.e. after all the retries have failed).

Remember, for expected failures, it's a better practice to handle them within the Service and return a status object.

A caught DeferredException in a workflow cannot be resumed, as the workflow has already "moved on".

DeferredException and its subclasses are the only relevant exceptions in workflows. Do not catch any other exceptions. Specifically, actual exceptions thrown in service or child-workflow workers are wrapped in the DeferredException. It is not meaningful to try to catch these exceptions directly.

Previous
Deferred