douglascrockford / parseq

Better living thru immediacy!
216 stars 28 forks source link

Uncaught exception when only last requestor succeed and the rest fail for Fallback and Race #10

Closed hacksave closed 4 years ago

hacksave commented 4 years ago

Using the provided demo application, trigger fallback in the following order: Fall F0: failure Fall F1: failure Fall F2: success A "Uncaught TypeError: callback is not a function" will be exception will happen. This only happen when last requestor in the array is the only wun that succeed while the rest fail.

Same exception also occur for race, when last requestor succeed while the rest fail Race B0: failure Race B1: failure Race B2: success

or

Race B0: failure Race B2: failure Race B1: success

Additionally, using race or fallback factory with only a single success requestor also cause the exception.

douglascrockford commented 4 years ago

I can not replicate your error. Can you please provide more information?

hacksave commented 4 years ago

Using a simplified version of the demo.js with the following:

parseq.fallback([
    widget("Fall F0"),
    widget("Fall F1"),
    widget("Fall F2")
])(show);

Click on the widget with the following order: Fall F0: failure Fall F1: failure Fall F2: success

An "Uncaught TypeError: callback is not a function" will occur.

The reason is due to such condition satisfy the two conditions statement inside race_action function.

if (value !== undefined) {
    cancel(make_reason(factory_name, "Loser.", number));
    callback(value);
    callback = undefined;
}

if (number_of_pending < 1) {
    cancel(reason);
    callback(undefined, reason);
    callback = undefined;
}

The value will be "Fall F2" and callback will be set to undefined. However, because its the last requestor in the array to succeed, number_of_pending is 0 and since callback has already been set to undefined, it cause the mentioned exception to occur.

Since fallback factory uses race factory behind the scenes, same thing happens for race using the following code:

parseq.race([
    widget("Race B0"),
    widget("Race B1"),
    widget("Race B2")
])(show);

Click on the widget with the following order: Race B0: failure Race B1: failure Race B2: success

Or the following order: Race B1: failure Race B2: failure Race B0: success

These will also trigger the same exception.

If it happen that a single requestor is use in fallback or race factory, the same mention exception will also occur. As it also satisfy the two conditions in race_action function.

parseq.fallback([
    widget("Task")
])(show);
douglascrockford commented 4 years ago

I am not seeing the behavior you are describing. Are you using the 2020-08-08 edition?

hacksave commented 4 years ago

Yes, I am using the latest code. Before reporting the issue, I cleared everything and downloaded the code again. I tried it in both Google Chrome & Firefox, Ctrl + F5 to refresh multiple times. Both produce the same error in the console.

douglascrockford commented 4 years ago

It is working perfectly for me. What could it be?

hacksave commented 4 years ago

That is very strange on why you can't trigger the error. I am clearly using the 2020-08-08 parseq.js as stated in the comment of the file.

I tried tracing the issue before reporting. The try inside the start_requestor function can only catch exception occur when the requestor is called. The action (which point to race_action function when using fallback / race factory) inside the start_requestor_callback function as part of the callback is not inside the try clause even though the code is looks like its inside try, since it is called at a later turn.

In your book under Exceptions in 20.9. "Exceptions are too weak to deal with failures happening over many turns." I guess this is a good example where I learn about it.

douglascrockford commented 4 years ago

I put the demo up at https://www.crockford.com/parseq_demo.html

Does it work for you there?

hacksave commented 4 years ago

I still have the exception. I linked the screenshot for easier understanding. It include both Google Chrome v86 and Firefox v82.

https://github.com/hacksave/hacksave.github.io/blob/main/firefox-82_fallback.jpg Fallback widget triggered in the following order: Fall F0: failure Fall F1: failure Fall F2: success

https://github.com/hacksave/hacksave.github.io/blob/main/firefox-82_race.jpg Race widget triggered in the following order: Race B0: failure Race B1: failure Race B2: success

https://github.com/hacksave/hacksave.github.io/blob/main/google-chrome-86_fallback.jpg Same as fallback above, but for Chrome.

https://github.com/hacksave/hacksave.github.io/blob/main/google-chrome-86_race.jpg Same as race above, but for Chrome

hacksave commented 4 years ago

I am running on Windows 10 and able reproduce the error on multiple machines with Windows 10. I am also able to reproduce it on Ubuntu 20.04 Firefox with same exception. I tried Microsoft Edge, just in case and had the same exception.

douglascrockford commented 4 years ago

Thank you very much for your perseverance and patience. Please try it now.

hacksave commented 4 years ago

Yes, I have tested the latest code and confirm its resolved. I learned a lot from it. Thanks.

douglascrockford commented 4 years ago

Please send me your PayPal email address.

hacksave commented 4 years ago

Thanks for asking. Its fine. Glad I am able to provide constructive feedback to this library.