elsa-workflows / elsa-workflows/elsa-core

Requesting TryCatch Activity Similar to System.Activities.Statements.TryCatch

Open
#6,578 0 comments 0 reactions 0 assignees View on GitHub
triaged
Dominant language
C#
Stars
7.9k
Forks
1.5k
Avg merge
15h 22m
Merged PRs (30d)
114

Description

## Feature Request

### Problem Overview
Currently there is no TryCatch like activity which can execute a child activity and even if there's any exception in the child activity. This is will be helpful to avoid faulting the entire workflow.

### Proposed Solution
1. Create a TryCatch activity with properties TryActivity, CatchActivity and FaultResult
2. Execute TryActivity inside a trycatch block.
3. In case of an exception, handle exception, set FaultResult, execute CatchActivity and continue its execution without faulting the workflow
4. If there is no exception, it should continue to its execute with rest of the workflow

### Alternative Solutions
If the above solution isn't feasible, we can try to handle it in middleware
1. Capture the exception in either ExecutionLogMiddleware or ExceptionHandlingMiddleware
2. Check if any one of the Faulted ancestors is TryCatch activity
3. Capture the exception and set the Fault information to TryCatch activity context.
4. Mark TryCatch activity as completed and proceed to the activity next to TryCatch activity

### Use Cases
1. Isolation of exception to specific segment instead of faulting entire workflow
2. Handling unreliable operations (like HTTP requests, complex SQL query execution)
3. Fallback Strategies

### Impact of Feature
1. Improved Workflow Robustness
2. Better Error Diagnostics and Recovery
3. Support for More Complex Scenarios

### Visuals and Mockups
[Activity("Elsa", "Primitives", "Try Catch", Kind = ActivityKind.Action)]
[FlowNode("Faulted", "Success")]
public class TryCatch : Activity
{
public Output FaultResult { get; set; } = default!;
[Port]
public IActivity? TryActivity { get; set; }
[Port]
public IActivity? CatchActivity { get; set; }

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
ExceptionState exceptionState = null;
try
{
//Execute TryActivity
}
catch (Exception ex)
{
exceptionState ??= ExceptionState.FromException(ex);
//Execute CatchActivity
}
finally
{
context.Set(FaultResult, exceptionState);

string outcome = ExceptionDetails != null ? "Faulted" : "Success";
await context.CompleteActivityAsync(new Outcomes(outcome));
}
}
}

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.