Prepare for coroutines
See original GitHub issueNow that we’re all ES6 for Sequelize v4, the door is open to be using coroutines. Personally, I think this is a great thing - it’ll simplify Sequelize’s codebase a lot.
However, I don’t think we’re quite ready to do that - I’d like to conclude my research on bluebird and CLS, to make absolutely sure that introducing coroutines won’t break CLS support, before we take the plunge.
But when we do start using coroutines, it will be a semver major change, due to a change in the way errors are handled.
Error handling
At present some Sequelize async methods throw synchronously if the arguments they are passed are illegal in some way. Once those methods become coroutines, this wouldn’t be the case any more - they’ll return rejected promises instead.
How it is now:
Model.findAll = function(options) {
if (!options) throw new Error('You must provide options!');
}
// Model.findAll() throws synchronously
try {
Model.findAll();
} catch (err) {
console.log('It throws!');
}
How it will be with coroutines:
Model.findAll = co.wrap( function*(options) {
if (!options) throw new Error('You must provide options!');
} );
// Model.findAll() returns a rejected promise
Model.findAll().catch( function(err) {
console.log('It returns a rejected promise');
} );
A proposal to “prepare the way”
I would like to see coroutines in Sequelize as soon as possible, but I don’t want to hold up the release of v4 until the CLS issues are resolved.
I propose that we “prepare the way” now by converting all Sequelize methods from throwing synchronously to returning rejected promises.
This isn’t hard to do using Promise.method()
:
Model.findAll = Promise.method( function(options) {
if (!options) throw new Error('You must provide options!');
} );
// Model.findAll() returns a rejected promise
Model.findAll().catch( function(err) {
console.log('It returns a rejected promise');
} );
This way:
- The whole API switches away from sync throwing in one go.
- It can all be done as a single change in Sequelize v4.0.0.
- Methods can then be refactored with coroutines as and when we feel like it, without creating any further breaking changes.
- We won’t have to wait until Sequelize v5 to start using coroutines.
What do you think?
Issue Analytics
- State:
- Created 7 years ago
- Comments:47 (46 by maintainers)
At present that would screw up CLS support - native promises don’t support CLS. But once async_hooks stabilises, CLS will use that underlying mechanism instead and that particular problem will go away. Give it a couple of months I’d say.
@felixfbecker Sorry yes, I wasn’t clear. I’m proposing that:
At present, a few async methods return a promise mostly, but in some circumstances throw synchronously instead. I’m proposing that they be altered to return a rejected promise rather than throwing.
I seem to remember there’s one method which sometimes returns a result sync and sometimes returns a promise (but I can’t remember which method it is!). This is a bit of an anti-pattern to my mind, and should probably be split into two methods, one always sync and one always async.
@mickhansen Do you know which method I’m talking about? My memory is that its sync/async behavior is dictated by a certain option that’s passed in.