Given a parallel state whose concurrent substates invoke some services, it appears that when you reject() a promise in order to fire onError in one substate, that XState is firing onError for ALL of the substates.
I have a parallel state with three concurrent substates (Q1, Q2, Q3). Each state attempts to pop() an element off of an array.
If the pop() is successful, the promise will resolve() and it will call the service's onDone. onDone just transitions to itself so the substate can repeat popping elements over and over.
When the array is empty, however, the pop() will fail and it should call onError. When onError is detected, it should transition to a 'final' state and wait there until the other Q's have also entered their 'final' state.
When ALL substates hit the 'final' state then the parallel state's onDone should fire as expected.
The parallel state's onDone is being triggered after only ONE substate has called onError.
That tells me that onError is causing the other substates' onError to be fired as well.
If it is intended that onError from one substate should cascade to other substates, then there is no sane way to implement retry logic. onError should be handled by only the substate that fired it, and leave it to that substate to communicate an error that should cascade.
The behavior is reproduced in this sandbox: https://codesandbox.io/s/1owjq73763
All of the code is in src/components/HelloWorld.vue
The console demonstrates:
1) When the first Q rejects() based on popping an empty array and calls onError,
2) ALL of the other substates' onError trigger, and
3) cause ALL substates to go to their 'final' state, which
4) forces the final onDone to be called before the other substates are actually done.
We should not see "finish" before we see any "fetchQueue:Qn:slept=x".
I've tried to debug this a little bit, at this point I'm not yet able to fix the issue at hand - but those are my findings:
onError on each parallel state gets invoked
Most helpful comment
I've tried to debug this a little bit, at this point I'm not yet able to fix the issue at hand - but those are my findings:
onErroron each parallel state gets invoked