flyd
flyd copied to clipboard
Internal state breaks on errors within an `on` listener?
I was getting the weirdest error, and it took me a while, but I reduced my code to this:
const flyd = require('flyd');
const run = assert => {
process.on('uncaughtException', (e) => {
console.log('Uncaught exception:', e);
});
const letter = flyd.stream('a');
const uppercaseLetter = flyd.map(l => l.toUpperCase(), letter);
console.log('Weird stuff here:', letter(), uppercaseLetter());
setTimeout(() => letter('b'), 0);
flyd.on(l => { if (l === 'b') throw "Error on purpose." }, letter);
};
run();
setTimeout(run, 0);
For which I get this output (Node v9.7.1):
Weird stuff here: a A
Uncaught exception: Error on purpose.
Weird stuff here: a undefined
Notice how the letter stream has the correct initial value both times, while the mapped stream uppercaseLetter breaks after an exception is thrown. Both times the streams and everything else are recreated from scratch, so my guess is that something seriously breaks in flyd's internal state when an exception is thrown while running on listeners...
By the way, thanks for flyd, and keep up the good work!
As of now you need to handle errors on your side.
When an error occurs in a stream body the internal state of flyd is corrupted (the inStream variable). There've been some discussions about how flyd should handle errors but nothing conclusive as of yet.
By "handle errors on your side", do you mean wrapping the contents of every subscribing function in a try/catch block? Hm.
For what is worth, this case arose in my intentionally breaking stuff for my tests, and while the code is supposed to exit the process, for the tests of course I'm trying to avoid that.
Duplicate of #164
For now, flyd gives atomic updates without any error handling.
Exceptions inside a stream subscription function have no guarantee that any stream in that dependency graph will be valid in the end.
For code that can fail, you'll need to wrap it in a try...catch -- this includes subscribed 'on' functions.
Okay, thank you.