question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Prepare for coroutines

See original GitHub issue

Now 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:

  1. The whole API switches away from sync throwing in one go.
  2. It can all be done as a single change in Sequelize v4.0.0.
  3. Methods can then be refactored with coroutines as and when we feel like it, without creating any further breaking changes.
  4. We won’t have to wait until Sequelize v5 to start using coroutines.

What do you think?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:47 (46 by maintainers)

github_iconTop GitHub Comments

1reaction
overlookmotelcommented, Jun 30, 2017

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.

1reaction
overlookmotelcommented, Sep 7, 2016

@felixfbecker Sorry yes, I wasn’t clear. I’m proposing that:

  • Sync methods should always return a value synchronously or throw synchronously
  • Async methods should always return a promise, which either resolves with a value or rejects with an error

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Coroutines for beginners: the only article you'll need to get ...
1. Say, what are Coroutines? · 2. Suspend Functions · 3. Starting a coroutine with Coroutine Builders · 4. Coroutine Dispatchers · 5....
Read more >
How to use Kotlin coroutines to complete complex tasks ...
Prepare your app to use coroutines ... To use coroutines, you first must appropriately configure your app using a toolkit called Gradle. Navigate...
Read more >
The Beginner's Guide to Kotlin Coroutine Internals
Bookkeeping to prepare for coroutine state to pass into the continuation; Running the coroutine code block (recall from the Language section how ...
Read more >
Kotlin Coroutines Cheat Sheet - Kt. Academy
This is why we prepared a special page just about Kotlin coroutines. Enjoy :) Sign up to our newsletter to get the PDF...
Read more >
Introduction to coroutines - Android Developers
Introduction to coroutines · Knowledge of basic Kotlin programming concepts including loops and functions, taught in Pathway 1: Introduction to ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found