Hi I have a problem in state machine and I really don't know what to do anymore. The thing is that the state machine works as it should, but if an exception occurs in the consumer from the DataRunningFault message, it correctly switches the state to ClearDataState and waits to see if DataCalculated or DataReport is running (the error in the consumer can occur after the DataCalculated/DataReport message is sent). Thus, I wait to see if it runs and if it does, I delete the data. More or less it works, but I get this exception.
public class DataState : SagaStateMachineInstance
{
public Guid CorrelationId { get; set; }
public int CurrentState { get; set; }
public int ReadyEventStatus { get; set; }
public Guid RequestId { get; set; }
}
public class DataStateMachine : MassTransitStateMachine<DataState>
{
public Event<DataRequested>? DatakRequested { get; }
public Event<Fault<DataRequested>>? DataRequestedFault { get; }
public Event<DataRunning>? DataRunning { get; }
public Event<Fault<DataRunning>>? DataRunningFault { get; }
public Event<DataCalculated> DataCalculated { get; }
public Event<Fault<DataCalculated>>? DataCalculatedFault { get; }
public Event<DataReport> DataReport { get; }
public Event<Fault<DataReport>>? DataReportFault { get; }
public MassTransit.Event? Finished { get; }
public State? ClearDataState { get; }
public DataStateMachine()
{
InstanceState(x => x.CurrentState);
Event(() => DataRequested, x => x.CorrelateById(context => context.Message.RequestId));
Event(() => DataRequestFault, x => x.CorrelateById(context => context.Message.Message.RequestId));
Event(() => DataRunning, x => x.CorrelateById(context => context.Message.RequestId));
Event(() => DataRunningFault, x => x.CorrelateById(context => context.Message.Message.RequestId));
Event(() => DataCalculated, x => x.CorrelateById(context => context.Message.RequestId));
Event(() => DataCalculatedFault, x => x.CorrelateById(context => context.Message.Message.RequestId));
Event(() => DataReport, x => x.CorrelateById(context => context.Message.RequestId));
Event(() => DataReportFault, x => x.CorrelateById(context => context.Message.Message.RequestId));
Initially(
When(DataRequested)
.Then(x =>
{
x.Saga.Entities = x.Message.Entities;
x.Saga.BatchDate = x.Message.BatchDate;
x.Saga.RequestId = x.Message.RequestId;
}),
When(DataRequestFault)
.Publish(x => Fault(x.Saga))
.TransitionTo(ClearDataState),
When(DataRunning),
When(DataRunningFault)
.Publish(x => Fault(x.Saga))
.TransitionTo(ClearDataState),
When(DataCalculated),
When(DataCalculatedFault)
.Publish(x => Fault(x.Saga))
.Finalize(),
When(DataReport),
When(DataReportFault)
.Publish(x => Fault(x.Saga))
.Finalize()
);
During(ClearDataState,
When(DataCalculated)
.Publish(x => new DeleteCalculateData() { RequestId = x.Message.RequestId })
.Finalize(),
When(DataReport)
.Publish(x => new DeleteCalculateData() { RequestId = x.Message.RequestId })
.Finalize()
);
CompositeEvent(() => Finished,
x => x.ReadyEventStatus,
CompositeEventOptions.IncludeInitial,
DataRequested,
DataRunning,
DataCalculated
);
During(Initial,
When(Finished)
.Publish(context =>
{
return new DataFinished() { RequestId = context.Saga.RequestId };
})
.Finalize()
);
SetCompletedWhenFinalized();
}
private DataFinishedFault Fault(RunDataState runDataState)
{
return new DataFinishedFault() { RequestId = runDataState.RequestId };
}
}
Exception:
MassTransit: Error: R-FAULT sb://testbusfortestingstandard.servicebus.windows.net/messaging-run-data-state bca30000-4395-e04f-ceb8-08dbe1bde727 SharedContracts.Messages.ReportCalculateFinished Messaging.StateMachines.DataState(00:00:00.8759128)
MassTransit.NotAcceptedStateMachineException: Messaging.StateMachines.DataState(63331cb1-6165-4260-9577-66be080a3d9e) Saga exception on receipt of SharedContracts.Messages.DataReport: Not accepted in state Final
---> MassTransit.UnhandledEventException: The DataReport event is not handled during the Final state for the DataStateMachine state machine
at MassTransit.MassTransitStateMachine`1.DefaultUnhandledEventCallback(UnhandledEventContext`1 context) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 219
at MassTransit.MassTransitStateMachine`1.UnhandledEvent(BehaviorContext`1 context, State state) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 1260
at MassTransit.MassTransitStateMachine`1.<.ctor>b__13_2(BehaviorContext`1 context, State state) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 52
at MassTransit.SagaStateMachine.StateMachineState`1.MassTransit.State<TSaga>.Raise[T](BehaviorContext`2 context) in /_/src/MassTransit/SagaStateMachine/SagaStateMachine/StateMachineState.cs:line 162
at MassTransit.MassTransitStateMachine`1.MassTransit.StateMachine<TInstance>.RaiseEvent[T](BehaviorContext`2 context) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 132
at MassTransit.Middleware.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next) in /_/src/MassTransit/Middleware/StateMachineSagaMessageFilter.cs:line 66
--- End of inner exception stack trace ---
at MassTransit.Middleware.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next) in /_/src/MassTransit/Middleware/StateMachineSagaMessageFilter.cs:line 81
at MassTransit.Middleware.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next) in /_/src/MassTransit/Middleware/StateMachineSagaMessageFilter.cs:line 104
at MassTransit.Middleware.SendSagaPipe`2.Send(SagaRepositoryContext`2 context) in /_/src/MassTransit/Middleware/SendSagaPipe.cs:line 43
at MassTransit.Middleware.SendSagaPipe`2.Send(SagaRepositoryContext`2 context) in /_/src/MassTransit/Middleware/SendSagaPipe.cs:line 67
at MassTransit.Saga.InMemorySagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Sagas/Saga/InMemoryRepository/InMemorySagaRepositoryContextFactory.cs:line 40
at MassTransit.DependencyInjection.DependencyInjectionSagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, Func`3 send) in /_/src/MassTransit/DependencyInjection/DependencyInjection/DependencyInjectionSagaRepositoryContextFactory.cs:line 101
at MassTransit.DependencyInjection.DependencyInjectionSagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, Func`3 send) in /_/src/MassTransit/DependencyInjection/DependencyInjection/DependencyInjectionSagaRepositoryContextFactory.cs:line 110
at MassTransit.Middleware.CorrelatedSagaFilter`2.Send(ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Middleware/CorrelatedSagaFilter.cs:line 45
I tried looking for a solution on the internet and moving events to other states or adding the state to the instancestate, but nothing helped.
The
Finalstate is meant to be a terminal state, and once a state machine transitions to theFinalstate, it should not accept any more events.DataReportevent in theFinalstate, which is not allowed.DataReportin theClearDataStateis to perform some finalization logic, you can move that logic to a different state that comes before theFinalstate.If the purpose of handlingDataReportin theClearDataStateis to perform some finalization logic, you can move that logic to a different state that comes before theFinalstate.ClearDataStatestate, it handles theDataCalculatedandDataReportevents, publishing the corresponding messages and finalizing the state.Finishedevent is received during theInitialstate, it publishes aDataFinishedmessage and finalizes the state.