Why do I not get the warning “a promise was create

2019-05-17 18:21发布

Edit: to be more clear - I'm NOT getting warning in example below. I would like to know why and see example code where warning would be printed.

In my Node.js project I'm using bluebird Promises library. I observed some cases where I'm getting following warning:

Warning: a promise was created in a handler but was not returned from it

I understand that the problem occurs when there is promise that is not connected to any promise chain.

I'm trying to fully understand how this works and what exactly the problem is in mentioned case. For that purpose I took example from the documentation.

Here is example of my code based on the example from the documentation for which I'm not getting any warning:

const Promise = require('bluebird');

function getUser() {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log('get user');
            resolve('userId');
        }, 4000);
    });
}

function getUserData(userId) {
    new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log('get user data');
            resolve('userData');
        }, 5000);
    });
}

getUser().then(function(user) {
    getUserData(user);
}).then(function(userData) {
    // userData is undefined as expected
    console.log('Data: ', userData);
});

Console output:

/usr/local/opt/node@6/bin/node test.js
get user
Data:  undefined
get user data

Process finished with exit code 0

Does anyone know why there is no warning in my case and how to reproduce it?

Edit: I'm using Node v6.11.3 and Bluebird 3.1.1

Based on answer from Pierre Clocher I tried also following:

getUser().then(function(user) {
    getUserData(user);
}).then(function(userData) {
    console.log('Data: ', userData);
    // userData is undefined
    throw new Error();
}).catch(function (error) {
    console.log('error: ', error);
});

There was also no any warning.

Console output:

/usr/local/opt/node@6/bin/node test.js
get user
Data:  undefined
error:  Error
    at test.js:64:11
    at tryCatcher (/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:672:20)
    at tryOnImmediate (timers.js:645:5)
    at processImmediate [as _immediateCallback] (timers.js:617:5)
get user data

Process finished with exit code 0

Checking Bluebird.js source

If someone is more familiar with Bluebird source, i've searched across source and find where there is check for warning (link to source):

if (returnValue === undefined && promiseCreated !== null &&
        wForgottenReturn) {
....

}
var msg = "a promise was created in a " + name +
    "handler " + handlerLine + "but was not returned from it, " +
    "see <link to goo.gl removed>" +
    creatorLine;
promise._warn(msg, true, promiseCreated);

Using debugger I checked, returnValue was undefined in my case, wForgottenReturn flag was set to true but promiseCreated was null and hence warning was not printed. I would interpret this like Promise via getUserData(user) in my example was not detected as created/unhandled.

3条回答
smile是对你的礼貌
2楼-- · 2019-05-17 18:54

You need to write return inside then callback.

.then(function(data){return getusersata()})

And such way you need to return promise inside getuserdata

return new Promise
查看更多
孤傲高冷的网名
3楼-- · 2019-05-17 18:59

I will answer my own question because I found where the catch is.

Short answer: the problem is that warnings are printed in console only when this is enabled by configuration.

Explanation:

While searching on web I found this issue reported on Bluebird github. In the example code I saw that they manually updated Bluebird config using following code:

Promise.config({
    warnings: true,
    longStackTraces: true
});

I did the same before running my code:

Promise.config({
    warnings: true,
    longStackTraces: true
});

function getUser() {
    ...
}

function getUserData(userId) {
    ...
}

getUser().then(function(user) {
    getUserData(user);
}).then(function(userData) {
    // userData is undefined as expected
    console.log('Data: ', userData);
});

and output was finally with warning:

/usr/local/opt/node@6/bin/node test.js
get user
(node:96276) Warning: a promise was created in a handler at test.js:71:5 but was not returned from it, see <goo.gl link removed>
    at new Promise (node_modules/bluebird/js/release/promise.js:79:10)
Data:  undefined
get user data

Process finished with exit code 0

Checking further I also find that there is no need to manually set Bluebird configuration to see warnings in case if NODE_ENV variable is set to "development". In case of "development" such features are enabled automatically. This is also described in this API reference.

查看更多
▲ chillily
4楼-- · 2019-05-17 19:16

The problem is that an error was thrown and you don't have any .catch() method on your promise flow. You're example doesn't throw anything that's why you dont have any warning.

Try that and you'll see the warning :

getUser().then(function(user) {
    return getUserData(user);
}).then(function(userData) {
    // userData is undefined => now it is (you need to return previous Promise)
   throw new Error(); 
});

Here the warning will appear because of the error. But if you add .catch(console.error) it won't.

查看更多
登录 后发表回答