JS - 未处理的承诺

JS - Unhandled promise

我创建了一个 node.js 网络应用程序。目前我正在为数据库使用 MSSQL。我添加了 node-mssql 包。我在一个名为 sql.js 的单独文件中创建了函数,以执行相应的 SQL 函数。 controller.js 使用 await 关键字调用它们。当我一次发出一个请求时我没有错误,但是如果两个请求大约同时出现,我会收到以下错误。

(node:136648) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: error is not defined
(node:136648) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我想我与连接有关,我使用的是全局连接,但我调试了 controller.js 并看到池已定义,所以我不确定是什么导致了这个问题。

SQL.js

const sql = require('mssql'); 
const config = {
    user: 'admin',
    password: 'linux',
    server: '11.222.33.44',
    database: 'master'
}
const pool = new sql.ConnectionPool(config); 
pool.on('error', err => {
    if (err) {
        console.log('sql errors', err);
    }
    if (!err) {
        pool.connect();
    }
});
module.exports.getUsers = async() => {
    // const pool = await sql.connect(config);
    try{
        const result  = await pool.request()
            .query(`SELECT * FROM master.dbo.users ORDER BY user_id`)
        // sql.close();
        return result.recordset; 
    }catch(err){
        throw error; 
    }
}
module.exports.getProducts = async() => {
    // const pool = await sql.connect(config);
    try{
        const result  = await pool.request()
            .query(`SELECT * FROM master.dbo.products ORDER BY product_zip`)
        // sql.close();
        return result.recordset; 
    }catch(err){
        throw error; 
    }
}

controller.js

const express = require('express');
const {getInfo, getUsers, getProducts} = require('../lib/sql');
const router = express.Router();

...

/// Get Users
router.get('/controller/getUsers', async(req, res, next) => {
    console.log('get: /controller/getUsers'); 
    const users = await getUsers(); 
    res.status(200).json(users);   
});
/// Get Products
router.get('/controller/getProducts', async(req, res, next) => {
    console.log('get: /controller/getProducts'); 
    const products = await getProducts(); 
    res.status(200).json(products);
});
module.exports = router;

您的各种 router.get 回调中没有错误处理,并且 router.get 没有对 return 值 做任何事情你传递给它的函数,所以如果你传递给它一个 async 函数,函数 returns 的承诺将不会被处理,而对于 rejected 承诺,那就是未处理的错误。因此出现错误消息。

相反:您必须处理错误。例如:

router.get('/controller/getUsers', async(req, res, next) => {
    try {
        console.log('get: /controller/getUsers'); 
        const users = await getUsers(); 
        res.status(200).json(templates);
    } catch (e) {
        res.status(500).send(/*...*/);
    }
});

那仍然 return 是一个从未处理过的承诺,但至少它从不 拒绝 (假设 catch 代码中没有任何失败)。

如果您有 returning 错误的通用方法,您可能想给自己一个围绕 router.get(等等)的包装函数来处理来自回调的错误,以便很好地集中处理。

例如:

const asyncRouterGet = (route, handler) => {
    return router.get(route, (req, res, next) => {
        handler(req, res, next)
        .catch(err => {
            // Common error handling here
            res.status(500).send(/*...*/);
        });
    });
};

然后

asyncRouterGet('/controller/getUsers', async(req, res, next) => {
    console.log('get: /controller/getUsers'); 
    const users = await getUsers(); 
    res.status(200).json(templates);
});

...因为您知道拒绝将由 asyncRouterGet 生成的回调自动处理。


显然,不要这样做:

try {
    // ...
}
catch (err) {
    throw error;
}

error 未在您引用的代码中的任何位置定义,并且

try {
    // ...
}
catch (err) {
    throw err;
}

没有意义;如果您不做任何其他事情而要重新抛出,请关闭 try/catch