Express App中的UnhandledPromiseRejectionWarning

时间:2018-09-18 20:37:11

标签: javascript node.js express promise

我目前正在学习Javascript / Node.js / MEAN堆栈,并且正在关注Express教程。

我收到以下错误:

  

(节点:11524)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):TypeError:无法读取未定义的属性“ close”   (节点:11524)[DEP0018] DeprecationWarning:已弃用未处理的承诺拒绝。将来,未处理的承诺拒绝将以非零退出代码终止Node.js进程。

当我在浏览器中点击此路线时。

function router(nav) {
adminRouter.route('/')
    .get((req, res) => {
        const url = 'mongodb://localhost:27017';
        const dbName = 'libraryApp';

        (async function mongo() {
            let client;
            try {
                client = await mongoClient.connect(url);
                debug('Connected correctly to server');

                const db = client.db(dbName);

                const response = await db.collection('books').insertMany(books);
                res.json(response);
            } catch (err) {
                debug(err.stack);
            }
            client.close();
        }());
    });

return adminRouter;

}

有人可以指出问题并解释问题的原因。

1 个答案:

答案 0 :(得分:1)

如果此行拒绝:

 client = await mongoClient.connect(url);

然后,您进入catch块,并在该catch块之后调用client.close()。但是,clientundefined,因此client.close()将抛出,此时您不在任何类型的try/catch内部。由于您位于async函数中,因此该抛出将变成已拒绝的承诺,而您没有.catch()要处理。因此,您最终会遇到无法处理的诺言拒绝。

您应该能够像这样修复它:

function router(nav) {
    adminRouter.route('/').get(async (req, res) => {
        const url = 'mongodb://localhost:27017';
        const dbName = 'libraryApp';

        let client;
        try {
            client = await mongoClient.connect(url);
            debug('Connected correctly to server');

            const db = client.db(dbName);

            const response = await db.collection('books').insertMany(books);
            res.json(response);
        } catch (err) {
            debug(err.stack);
            // make sure and send some response on errors
            res.sendStatus(500);
        }
        if (client) {
            client.close();
        }
    });
    return adminRouter;
}

这将进行一些更改:

  1. 在调用if (client)之前添加client.close(),以防止客户端未设置的情况发生。
  2. 将整个.get()回调设为async,而不要使用IIFE(不是必需的,对我来说似乎更干净)
  3. catch语句中发送错误状态和响应,因此即使在错误情况下,您始终会发送某种形式的http响应。

如果您真的想实现故障保护,则可以添加另一个try / catch:

function router(nav) {
    adminRouter.route('/').get(async (req, res) => {
        const url = 'mongodb://localhost:27017';
        const dbName = 'libraryApp';

        let client;
        try {
            client = await mongoClient.connect(url);
            debug('Connected correctly to server');

            const db = client.db(dbName);

            const response = await db.collection('books').insertMany(books);
            res.json(response);
        } catch (err) {
            debug(err.stack);
            // make sure and send some response on errors
            res.sendStatus(500);
        }
        try {
            if (client) {
                client.close();
            }
        } catch(e) {
            console.log("unable to close database connection");
        }
    });
    return adminRouter;
}