【问题标题】:try/catch block can't stop ER_DUP_ENTRY error from crashing my applictiontry/catch 块无法阻止 ER_DUP_ENTRY 错误使我的应用程序崩溃
【发布时间】:2020-08-17 18:31:35
【问题描述】:

我正在向 mysql 表添加一个副本,并且我想处理引发的 ER_DUP_ENTRY 错误,该错误以 Try/Catch 块返回,但它只是崩溃了,有没有可能的方法来处理错误并停止应用程序使用 try/catch 块崩溃?

async function init() {
    try {
      connection.query(
        'SOME INSERT QUERY',
        (err, result, feilds) => {
          if (err) throw err
          console.log(result);
        }
      );
    } catch (e) {
      console.log(e);
    }
  }

init(); 

【问题讨论】:

  • connection.query 是返回 Promise 还是使用回调?两者都做不到
  • @AlwaysLearning 是的,是的,我想它两者都有,我在这里用回调改变了它,但它并没有改变关于处理错误的主要问题的根源

标签: mysql node.js error-handling try-catch


【解决方案1】:

节点 mysql-library 不支持开箱即用的承诺,这意味着query 不会返回您可以等待的承诺。因此,您可以自己将 query 函数包装在一个 Promise 中:

async function init() {
    try {
        const duplicateResult = await new Promise((resolve, reject) => {
                connection.query(
                    'SOME INSERT QUERY',
                    (err, result, fields) => {
                    if (err) {
                        return reject(err);
                    }
                    resolve(result);
                });
            });

    } catch (e) {
        console.log(e);
    }
}

或使用 util.promisify 作为 Always Learning 的替代品。

【讨论】:

  • 您不能将try...catch 单独与回调一起使用——但这应该可以正常工作。使用回调时,需要在回调中自己处理错误。
  • 感谢@eol,它是真的并且确实有帮助.. 但是我把它改成了回调,你能解释一下为什么当我使用回调时它的行为是这样的吗?我的意思是,不应该是 try/catch块捕获所有抛出错误并避免崩溃?你可以看看我编辑的 q
  • 一旦回调被执行,try catch 块就已经执行了,这就是错误没有被捕获的原因。您需要处理回调中的错误,即if (err) // handle error。我强烈建议阅读nodejs.dev/the-nodejs-event-loop 以了解为什么会发生这种情况:)
  • 谢谢我知道事件循环是如何工作的,但它有点模糊地掌握它在 try/catch 中是如何工作的。如果我错了,请纠正我...我假设有某种功能仅在执行时应用于每个语句,现在它将等待该语句返回的内容。我正在使用 setTimeout 对其进行测试......我可能应该阅读更多关于 try/catch 正在使用的机制
【解决方案2】:

问题是connection.query 立即返回undefined。您的catch 不涉及,因为调用在工作完成之前结束,稍后将调用您的回调函数。回调期间发生的异常为时已晚。你的 try/catch 块已经完成了。

您可以使用promisify 来等待它,就像这样:

const util = require("util");
function init() {
  const queryPromise = util.promisify(connection.query);
  return queryPromise('SOME INSERT QUERY')
    .catch(e => {
      console.log("It failed", e);
    });
  }

init().then(result => {
  if (result) console.log("It worked", result);
  else console.log("Aww, it didn't work");
}); 

【讨论】:

  • 即使对于期望没有错误的查询也不起作用,但它有以下错误。它失败了 TypeError: Cannot read property 'typeCast' of undefined
  • 哪一行给出了这个错误?请注意 init() 将始终解决,即使内部的 catch 捕获错误,因为您没有重新抛出它,所以 result 在这种情况下可能是未定义的。您可以以不同的方式处理 catch 并重新抛出它,然后使用 init().then(...).catch(...) 来处理错误。我编辑了我的答案以显示更多错误处理。
  • 它可能与 queryPromise("SOME INESRT QUERY") 部分有关...我在这里共享工作区。 goor.me/ZoXQe
猜你喜欢
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多