繁体   English   中英

Promise中的Node.js MySQL错误处理

[英]Node.js mysql error handling in promise

我正在使用node.js并表达,也是mysql。 我使用连接池来请求连接并在其上创建承诺,以限制回调的噩梦,在我稍后导入的文件中设置了以下代码段,请注意,我设置了error处理程序,以防出现以下情况终止应用程序:真的出了什么问题

exports.getConnection = () => {
    return new Promise((resolve, reject) => {
        pool.getConnection((err, connection) => {
            if (err) {
                reject(`Could not obtain the connection from the pool: ${err}`);
            }
            connection.on('error', err => {
                console.log(`SQL error (code: ${err.code}, message: ${err.sqlMessage}) while executing query: ${err.sql}`);
            });
            resolve(connection);
        });
    });
};

这是一个用例示例(想法是获取连接,在then链接查询,如果发生非致命错误,我将其抛出并在catch处理程序中处理连接释放

// Exception handler that release the connection then call the callback
function releaseConnectionHandler(err, connection, callback) {
    connection.release();
    callback(err, null);
}
exports.someRequest = function(ID, callback) {
    sqlPool.getConnection().then(connection => {
        connection.query("SELECT * from tableNotExists",
                        (err, result) => {
            if (err) { 
                throw ({ err, connection, callback }); 
            }
            connection.release();
            callback(null, result);
            });
    }).catch(({ err, connection, callback}) => releaseConnectionHandler(err, connection, callback));
};

该查询将失败,但是我发现甚至没有调用该处理程序(我在其中添加了一些跟踪信息...),并且该应用程序终止于

node_modules/mysql/lib/protocol/Parser.js:80
        throw err; // Rethrow non-MySQL errors

正确的查询不会造成麻烦...任何想法我在错误处理上做错了什么?

您将重新传递传递给查询回调的错误,您正在使用的库也将重新引发该错误,最后在任何地方都无法正确捕获和处理该错误,从而导致失败。 throw ,您不在Promise的上下文中,而是从mysql模块调用的回调函数的上下文。

您也不必要混合使用Promise和回调,特别是要导出的功能。 您的问题表明您想摆脱回调,因此我将以该指示为基础。

要解决主要问题,请不要抛出错误。 而是将其传递给被调用者:

const promisify = require("util").promisify;

exports.someRequest = function (ID) {
  return sqlPool.getConnection().then(connection => {
    return promisify(connection.query)("select * from tableNotExist")
      .finally(connection.release);
  });
};

无论成功还是错误,连接将始终释放回池中。 然后可以使用以下方法调用该方法:

yourModule.someRequest(id).then((results) => {
  // Do something with the result set
}).catch((e) => {
  // Handle error. Can be either a pool connection error or a query error.
});

如果可以使用async/await ,则可以重写代码:

const promisify = require("util").promisify;

exports.someRequest = async function (ID) {
  let connection = await sqlPool.getConnection();
  try {
    return await promisify(connection.query)("select * from tableNotExist");
  } finally {
    connection.release();
  }
};

我还建议使用node-mysql2因为它们除了回调样式的API之外,还具有基于Promise的API,并且根据我的经验,它们的性能也更好。 然后,您不必编写这些繁琐的包装程序,而只require('mysql2/promise')就可以了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM