【问题标题】:UnhandledPromiseRejectionWarning in Express AppExpress 应用程序中的 UnhandledPromiseRejectionWarning
【发布时间】:2019-02-22 22:39:55
【问题描述】:

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

我收到以下错误:

(节点:11524)UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:1):TypeError:无法读取未定义的属性“关闭” (节点:11524)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 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;

}

有人可以指出问题并解释问题所在。

【问题讨论】:

    标签: javascript node.js express promise


    【解决方案1】:

    如果此行拒绝:

     client = await mongoClient.connect(url);
    

    然后,您转到您的 catch 块,在该 catch 块之后,您调用 client.close()。但是,clientundefined,所以 client.close() 会抛出,此时你不在任何类型的 try/catch 中。由于您在 async 函数中,因此该 throw 将变成一个拒绝的承诺,您没有 .catch() 可以处理。因此,您最终会得到一个未处理的 Promise 拒绝。

    你应该可以这样修复它:

    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. 在调用client.close() 之前添加if (client) 以保护它免受`client never got set。
    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;
    }
    

    【讨论】:

    • 谢谢你!一旦我回到我的机器,我将看看进行更改。但是从你所说的 - > client = await mongoClient.connect(url);这可能是我的 mongo DB 没有正确启动和运行,或者我没有正确连接到它。如果我能正常运行,我就不会被拒绝?
    猜你喜欢
    • 2020-10-17
    • 2019-11-14
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 2019-05-29
    相关资源
    最近更新 更多