Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork1.3k
-
In one of my states I am invoking a promise actor and have an input inside invoke. My invoke section includes onDone/onError and my input function could throw an error in some cases. I've just noticed that the onError transition is executed only for errors thrown from promise actor. |
BetaWas this translation helpful?Give feedback.
All reactions
👀 1
Replies: 2 comments 2 replies
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
I searched a lot across the issues and found some similar cases ( for example this one -#3645 ). From what I understand, when the machine is instantiated, we can subscribe to errors. But there is no way inside the machine to subscribe to that error and make a transition? One workaround that I see is to subscribe for error and once an error is caught we can send an event to the state machine and thus we can transition to the error state which is a final state? |
BetaWas this translation helpful?Give feedback.
All reactions
-
That's right, there is currently no way to do this for input creation errors itself. What would an intuitive API look like for you that would support this? |
BetaWas this translation helpful?Give feedback.
All reactions
-
As searching for a solution I found that there were typestates inxstate 4 which are not supported in xstate 5. Now I have some properties in Context that areset to null by default and during the state machine I populate them. In the following example I have to check whether userId is not null. If it is null I'm throwing an error as this is something that is not expected and what to move state-machine to a failure state. Example is not the best one as this case is mostly avoidable due typescript warnings - e.g. ts will warn if you write: But I make some more complex input functions that uses userId and also a mapping ( object that keeps userId to something ) and if there is not mapping for some userId I throw errors and then state machine stuck.
Not sure how intuitive is but as I found that we can subscribe to errors I decided to try if I can subscribe for error event in top levelon clause - This for example will help in some cases - when an error is a fatal one and want go to a final failure state where you can make some cleanup logic. But my case is a little bit different and I iterate over items - e.g. users and it can fail for some of the users and I want to skip these failures but to keep info about them. Maybe something likeonError at the same level asinvoke which handles errors from input/actions/guards |
BetaWas this translation helpful?Give feedback.
All reactions
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
I was about to open an issue but I found this one. import{createActor,fromPromise,setup}from"xstate"typeInput={shouldThrow:"input"|"actor"|"onDone"|null}constmyPromiseActor=fromPromise<string,Input>(({ input})=>{returnnewPromise((resolve,reject)=>{if(input.shouldThrow==="actor"){console.error("Throwing error from within the actor's promise.")reject(newError("Error from actor"))}else{resolve("Promise resolved")}})})constpromiseMachine=setup({types:{context:{}asInput,input:{}asInput},actors:{ myPromiseActor}}).createMachine({id:"promiseMachine",initial:"loading",context:({ input})=>input,states:{loading:{invoke:{src:"myPromiseActor",input:({ context})=>{if(context.shouldThrow==="input"){console.error("Throwing error from input function.")thrownewError("Error from input function")}returncontext},onDone:{target:"success",actions:({ context})=>{if(context.shouldThrow==="onDone"){console.error("Throwing error from within the onDone hook.")thrownewError("Error from onDone hook")}console.log("onDone hook executed successfully.")}},onError:{target:"failure",actions:()=>{console.error("Caught error")}}}},success:{type:"final"},failure:{type:"final"}}})constactor=createActor(promiseMachine,{input:{shouldThrow:"onDone"}}).start()actor.subscribe((state)=>{console.log("Current state:",state.value)})
One solution to these issue would be for onError to catch allErrors happening in input and in onDone. This could be enabled with a small flag (catchAll: true) to be backward compatible, and eventually be the default in v6. |
BetaWas this translation helpful?Give feedback.