Skip to content
This repository has been archived by the owner on Jul 5, 2018. It is now read-only.

Runs outside Fiber while using inside a Meteor package #16

Open
kamilkisiela opened this issue Sep 2, 2017 · 2 comments
Open

Runs outside Fiber while using inside a Meteor package #16

kamilkisiela opened this issue Sep 2, 2017 · 2 comments

Comments

@kamilkisiela
Copy link

kamilkisiela commented Sep 2, 2017

Issue

The issue occurs when using @accounts/graphql-api inside of a meteor package. If we'd create the same logic but inside an app, it'd work.

const resolver = {
  User: {
    foo: () => FooCollection.findOne()
  }
};
mutation login {
  loginWithPassword( /*...*/ ) {
    user {
      username
      foo {
        id
      }
    }
  }
}

Gives:

{
  "data": {
    "loginWithPassword": {
      "user": {
        "username": "foo",
        "foo": null
      }
    }
  },
  "errors": [
    {
      "message": "Can't wait without a fiber",
      "locations": [
        {
          "line": 5,
          "column": 7
        }
      ],
      "path": [
        "loginWithPassword",
        "user",
        "foo"
      ]
    }
  ]
}

Reproduction

Run it and go to http://localhost:3000. It should display SUCCESS or FAILURE.

Failure:

Meteor@1.5.2 or less
https://github.com/kamilkisiela/js-accounts-meteor-fiber/tree/failure

Success:

Meteor@1.6-alpha.0 at least
https://github.com/kamilkisiela/js-accounts-meteor-fiber/tree/success

Differences

kamilkisiela/js-accounts-meteor-fiber@failure...success

Idea

For me it's something to do with async/await and Promise. async/await is being compiled to something that uses asyncGeneratorFunction from babel-runtime's helpers and there's a Promise inside of it. For me, that Promise is not wrapped with a Fiber as it'd normally be in Meteor's environment.

@davidyaha davidyaha changed the title Runs outside Fiber Runs outside Fiber while using inside a Meteor package Sep 3, 2017
@kamilkisiela
Copy link
Author

babel-runtime/helpers/asyncToGenerator module uses a Promise from the core-js package.

Inside of core-js:

https://github.com/zloirock/core-js/blob/9bf000955a615307254cdb8861bfdc19c7184d77/library/modules/es6.promise.js#L26-L36

As you can see, USE_NATIVE value is boolean that tells if it should use native Promise or a polyfill.

I did some deep digging and it seems like at the time when an anonymous function executes to return a value for USE_NATIVE, there is a Promise available and it's wrapped with Fiber which is what we're looking for.

USE_NATIVE should be true but it's false. It happens because inside the try/catch an error occurs.

TypeError: es6PromiseThen.call is not a function

It points to this part of a code from meteor-promise package:

https://github.com/meteor/promise/blob/master/promise_server.js#L29-L33

@davidyaha
Copy link
Member

Thanks for the research @kamilkisiela!
I've actually faced this issue myself in a recent project (not in a package) and have just used the rawCollection() function of the meteor collection in order to get the native mongo driver Collection object and then ran my queries as documented by mongo.

I guess there is not much we can do here but wait to 1.6 to release and it will just give us a free fix :)

Leaving this open for anyone else that faces this issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants