diff --git a/src/WorkflowCore/Services/ExecutionResultProcessor.cs b/src/WorkflowCore/Services/ExecutionResultProcessor.cs index cdf0a9b42..730dbc911 100755 --- a/src/WorkflowCore/Services/ExecutionResultProcessor.cs +++ b/src/WorkflowCore/Services/ExecutionResultProcessor.cs @@ -110,8 +110,8 @@ public void HandleStepException(WorkflowInstance workflow, WorkflowDefinition de { var exceptionPointer = queue.Dequeue(); var exceptionStep = def.Steps.FindById(exceptionPointer.StepId); - var compensatingStepId = FindScopeCompensationStepId(workflow, def, exceptionPointer); - var errorOption = (exceptionStep.ErrorBehavior ?? (compensatingStepId.HasValue ? WorkflowErrorHandling.Compensate : def.DefaultErrorBehavior)); + var shouldCompensate = ShouldCompensate(workflow, def, exceptionPointer); + var errorOption = (exceptionStep.ErrorBehavior ?? (shouldCompensate ? WorkflowErrorHandling.Compensate : def.DefaultErrorBehavior)); foreach (var handler in _errorHandlers.Where(x => x.Type == errorOption)) { @@ -120,7 +120,7 @@ public void HandleStepException(WorkflowInstance workflow, WorkflowDefinition de } } - private int? FindScopeCompensationStepId(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer currentPointer) + private bool ShouldCompensate(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer currentPointer) { var scope = new Stack(currentPointer.Scope); scope.Push(currentPointer.Id); @@ -130,11 +130,11 @@ public void HandleStepException(WorkflowInstance workflow, WorkflowDefinition de var pointerId = scope.Pop(); var pointer = workflow.ExecutionPointers.FindById(pointerId); var step = def.Steps.FindById(pointer.StepId); - if (step.CompensationStepId.HasValue) - return step.CompensationStepId.Value; + if ((step.CompensationStepId.HasValue) || (step.RevertChildrenAfterCompensation)) + return true; } - return null; + return false; } } } \ No newline at end of file diff --git a/test/WorkflowCore.IntegrationTests/Scenarios/DynamicDataIOScenario.cs b/test/WorkflowCore.IntegrationTests/Scenarios/DynamicDataIOScenario.cs index 4c1c013ba..416db55f2 100644 --- a/test/WorkflowCore.IntegrationTests/Scenarios/DynamicDataIOScenario.cs +++ b/test/WorkflowCore.IntegrationTests/Scenarios/DynamicDataIOScenario.cs @@ -38,7 +38,7 @@ public int this[string propertyName] public class DataIOWorkflow : IWorkflow { - public string Id => "DataIOWorkflow"; + public string Id => "DynamicDataIOWorkflow"; public int Version => 1; public void Build(IWorkflowBuilder builder) { diff --git a/test/WorkflowCore.IntegrationTests/Scenarios/FailingSagaScenario.cs b/test/WorkflowCore.IntegrationTests/Scenarios/FailingSagaScenario.cs new file mode 100644 index 000000000..36c12c3bd --- /dev/null +++ b/test/WorkflowCore.IntegrationTests/Scenarios/FailingSagaScenario.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Text; +using WorkflowCore.Interface; +using WorkflowCore.Models; +using Xunit; +using FluentAssertions; +using System.Linq; +using WorkflowCore.Testing; + +namespace WorkflowCore.IntegrationTests.Scenarios +{ + public class FailingSagaScenario : WorkflowTest + { + public class Workflow : IWorkflow + { + public static int Event1Fired; + public static int Event2Fired; + public static int Event3Fired; + + public string Id => "NestedRetrySaga2Workflow"; + public int Version => 1; + public void Build(IWorkflowBuilder builder) + { + builder + .StartWith(context => ExecutionResult.Next()) + .Saga(x => x + .StartWith(context => ExecutionResult.Next()) + .If(data => true) + .Do(i => i + .StartWith(context => + { + Event1Fired++; + throw new Exception(); + }) + ) + .Then(context => Event2Fired++) + ) + .OnError(WorkflowErrorHandling.Terminate) + .Then(context => Event3Fired++); + } + } + + public FailingSagaScenario() + { + Setup(); + Workflow.Event1Fired = 0; + Workflow.Event2Fired = 0; + Workflow.Event3Fired = 0; + } + + [Fact] + public void Scenario() + { + var workflowId = StartWorkflow(null); + WaitForWorkflowToComplete(workflowId, TimeSpan.FromSeconds(30)); + + GetStatus(workflowId).Should().Be(WorkflowStatus.Terminated); + UnhandledStepErrors.Count.Should().Be(1); + Workflow.Event1Fired.Should().Be(1); + Workflow.Event2Fired.Should().Be(0); + Workflow.Event3Fired.Should().Be(0); + } + } +}