-
Notifications
You must be signed in to change notification settings - Fork 73
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
Do not override resolve
and reject
functions with null
#66
Conversation
Promise resolver, the `function(success, error)`, is called synchronously. This is documented behavior of `bluebird`. However callback passed to `self.exec` is expected to be called asynchronously, but it is actually called synchronously in case of CastError. Calling callback passed to `self.exec` asynchronously will require careful refactoring, leaving the root cause aside, we can fix one use case right now with small change. I propose to remove setting `resolve` and `reject` to null as a fix for this use case, as it does not make sense to null them: these variables are not accessible from callback scope, thus they will not be put in environment when executing callback, so they will be eventually cleared by GC. Consider following code: ``` Model.findOne({ numericProperty: '1a' }).then(success, error); ``` It is expected to execute error asynchronously, but it actually try to call it synchronously after setting `reject` to `null` and fail with ``` Warning: .then() only accepts functions but was passed: [object Null], [object Null] at Query.then ([path]\node_modules\mongoose\node_modules\mquery\lib\mquery.js:2354:18) ... Unhandled rejection CastError: Cast to number failed for value "1a" at path "numericProperty" at SchemaNumber.cast ([path]\node_modules\mongoose\lib\schema\number.js:217:9) ```
Hmm could we just work around this by wrapping the |
I think the root issue should be fixed in mongoose, in the code that calls callback synchronously. Can not check it right now, but I assume the issue is in mongoose's Promise implementation which calls listeners synchronously. Leaving mongoose aside, is there a point in setting three variables from patch to null? |
I think the general idea is that subsequent calls to then() error out. FWIW, this is a bug in bluebird and probably should be fixed there, Promises/A+ 2.2.1 specifies that rejected must be called asynchronously. |
@vkarpov15 This is not a bluebird's bug, there is one in mquery for If there is no objections to proposed change, please apply it to allow catching casting errors, as fixing mpromise may be a complex task, which does not make sense as it may be replaced with other libraries in future. |
@vkarpov15 I think this issue possibly suffered from some poor communication. Let me know your thoughts please.
Does the Promise/A+ spec cover how a promise is created? It wasn't obvious to me if it does.
Do you know off hand if this is the case with mpromise? Are CastErrors called synchronously on the cb or onRejected() of the promise? I'm interested in this issue as I see Bluebird complaining often about Mongoose CastErrors in our app. |
Promise resolver, the
function(success, error)
, is called synchronously. This is documented behavior ofbluebird
. However callback passed toself.exec
is expected to be called asynchronously, but it is actually called synchronously in case ofCastError
(happening on mongoose side).Calling callback passed to
self.exec
asynchronously will require careful refactoring, leaving the root cause aside, we can fix one use case right now with small change. I propose to remove settingresolve
andreject
to null as a fix for this use case, as it does not make sense to null them: these variables are not accessible from callback scope, thus they will not be put in environment when executing callback, so they will be eventually cleared by GC.Consider following mongoose code:
It is expected to execute error asynchronously, but it actually try to call it synchronously after setting
reject
tonull
and fail with