-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Broken promise behaviour when types used in list have async field resolve functions. #17
Comments
Alright, well, I think I have a reasonable handle on the codebase now, thanks to a lot of node-inspectoring ;). Here's a much simpler proof of the bug:
Which results in
but if you change orgType.id.resolve to just return a value, you get
as expected. Here's what's happening:
Fix?The simplest fix would be to add the following between these two lines: https://github.com/graphql/graphql-js/blob/master/src/executor/executor.js#L469-L470 but I don't know the codebase well enough to know if this should move into isThenable in case there are similar issues elsewhere? Or if it should be in resolveFieldOrError maybe?
Thoughts? I can try and add a test to the star wars stuff that demonstrates this if required once I have a little more time. |
Thanks for your in-depth exploration! There are some minor issues with your fix surrounding nullable vs non-nullable error handling, but it's directionally sound. I'll investigate further. |
So here's the result of my further analysis: The library hadn't supported this yet not as a bug but because we assumed if a resolve function would return a list of promises, that the resolve function itself would be responsible for calling As I was thinking about this further, I think we're also missing a case where a list without non-null item type So a list of promises:
should result in More investigation and test writing is necessary, but thanks again for highlighting! |
Thanks! I'm not sure I agree though, in this case my resolve functions are only ever returning individual promises, but it's the lib itself which is creating an array of promises when it maps over a list type, no? Philip Roberts
|
Ah yes, I think there are two subtle overlapping issues here. I see from your test case that there is another failure to resolve the promise before continuing. Thanks for providing them, I'll make sure they get encoded as runtime unit tests. |
Thanks @leebyron! Yeah, it was quite hard to produce a minimal testcase that demonstrated the behaviour, while still demonstrating the intent :) |
@latentflip please check out 0fd8be1 and let me know if the test cases I added are aligning with the issues you ran into. |
Version 0.1.2 is on npm that includes that commit |
@leebyron yup, just ran it on the test-cases + orm integration I've been working on and it's looking good. Thanks for the quick turnaround! 🎉 |
Thank YOU for playing with it in such an early state and investigating. I may not have found this issue otherwise. |
Having almost same problem. I try to use type of "Customer" which fetch some data from SQL and some from MongoDb.
All fields comes from SQL besides "quiz", resolve method for "quiz" return Mongoose promise which then return array of object. But on this query:
I get:
Any solution so far? |
Okay, I'm still digging into this, and trying to simplify my examples, but it looks like something funky is going on with field resolve behaviour when promises are returned.
Here's example code which demonstrates the behaviour (as well as the results) https://gist.github.com/latentflip/f1c9520ac0d83b5237fc note how in the results, projectPromises differs from projectResults.
Okay, to explain further, the basic setup I have is:
and my root query just returns one org, so the query I'm executing is:
which should return the org, all it's projects, and all their versions.
However, it seems if my
projects.versions
resolve function returns a promise, instead of immediately returning an array, something breaks. To demonstrate, in the actual code linked above, I've got a ProjectReturnType which just returns an array for it's versions and a ProjectPromiseType which returns the same array, but wrapped in aPromise.resolve()
. The latter seems to break theprojectPromises
in the response completely, and it just returns{}
.As I understand it, a resolve function returning a value, or a resolve function returning a promise of that same value, should be exactly equivalent, right?
The text was updated successfully, but these errors were encountered: