简体   繁体   English

Promise拒绝未捕获节点mysql错误

[英]Node mysql error is not being caught by Promise reject

I'm making a simple database call wrapped in a promise, and trying to catch the error and pass it through to the promise reject(), but the reject isn't being handled or bubbled back up by the calling code.我正在进行一个包含在承诺中的简单数据库调用,并尝试捕获错误并将其传递给承诺拒绝(),但拒绝没有被调用代码处理或冒泡。 The code just stops executing when the mysql call fails.当 mysql 调用失败时,代码将停止执​​行。

The error within the mysql callback is: mysql 回调中的错误是:

REJECTING QUERY { Error: You have an error in your SQL syntax; REJECTING QUERY { 错误:您的 SQL 语法有错误; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?'检查与您的 MariaDB 服务器版本相对应的手册,了解在“?”附近使用的正确语法。 at line 1在第 1 行

Here is the database query code:下面是数据库查询代码:

this.query = function(sql, params) {
    return new Promise((resolve, reject) => {
        _pool.query(sql, params, function(err, result) {
            if (err) {
                console.log("REJECTING QUERY", err);
                return reject(err);
            }
            resolve(result);
        });
    });
}

Here is the calling code:这是调用代码:

this.createUser = function(data) {
    var query = "INSERT into users SET ?";

    return new Promise((resolve, reject) => {
        Container.DB.query(query, data)
            .then((response) => {
                console.log("Resolved", response);
                return resolve(response);
            },(error) => {
                console.log("REJECTION ERROR", error);
                return reject('An unknown error occurred and has been reported.');
            })
            .catch((err) => {
                console.log("CAUGHT ERROR", err);
            });
    });
}

I get to "REJECTING QUERY" within the database query code, but nothing in the calling code is reached (ie. .then, or the error handler, or the .catch handler).我在数据库查询代码中进入“拒绝查询”,但没有到达调用代码中的任何内容(即 .then、错误处理程序或 .catch 处理程序)。 Is it possible to get the mysql error to reach these points in code so I can respond to the user?是否有可能在代码中获得 mysql 错误以达到这些点,以便我可以响应用户? Am I doing something wrong?难道我做错了什么?

The anti-pattern mentioned by @JaromandaX is forcing you to unnecessarily jump through flaming hoops to accommodate it... and your getting burned. @JaromandaX 提到的反模式迫使你不必要地跳过燃烧的箍来适应它......你会被烧伤。

But, first, you are rejecting to the outer (redundant) promise from the then before the catch so the catch is by-passed.但是,首先,您在catch之前拒绝了来自then的外部(冗余)承诺,因此catchcatch After an error is thrown in a promise chain, the first thenable with a second argument ( onRejected ) will consume it: so it won't be propagated beyond that.的误差在一个承诺链抛出后,用第二个参数(onRejected)第一thenable将消耗它:所以它不会被传播超出。 But, anyway, you need to trap the error on the outer promise which you are rejecting.但是,无论如何,您需要将错误捕获在您拒绝的外部承诺上。

this.createUser = function (data) {
  var query = "INSERT into users SET ?";

  return new Promise((resolve, reject) => {  //   the first 'then' rejects to here
    Container.DB.query(query, data)          //   broken promise: anti-pattern
      .then((response) => {
        console.log("Resolved", response);
        return resolve(response);
      }, (error) => {
        console.log("REJECTION ERROR", error);//<--the error is consumed here and will
                                              //   not go any further on this chain
        return reject('An unknown error occurred and has been reported.');
      })
      .catch((err) => {                       //   this will not be called
        console.log("CAUGHT ERROR", err);     //   because it is the 'onRejected'
                                              //   argument of a then
      });
  })
    .catch((err) => {   // this will be called and the error will be consumed
      console.log("CAUGHT ERROR", err);
      return 'An unknown error occurred and has been reported.';
    });
  ;
}

Less worse, you can log and re-throw the error in one catch ...更糟糕的是,您可以在一次catch记录并重新抛出错误......

this.createUser = function (data) {
  var query = "INSERT into users SET ?";

  return new Promise((resolve, reject) => {  // this is still redundant
    Container.DB.query(query, data)          // broken promise: anti-pattern
      .then((response) => {                  // on error, skip this because it has no
        console.log("Resolved", response);   // 'onRejected' argument
        return resolve(response);
      })
      .catch((err) => {                      // this will be called and the error
        console.log("CAUGHT ERROR", err);    // will be consumed
        return reject('An unknown error occurred and has been reported.');
      });
  })
    ;
}

Better, eliminate the anti-pattern and propagate the message with a throw instead of a reject on the (redundant) promise wrapper...更好的是,消除反模式并在(冗余)承诺包装器上使用throw而不是reject来传播消息......

this.createUser = function (data) {
  var query = "INSERT into users SET ?";

  return Container.DB.query(query, data)
    .then((response) => {                  // on error, skip this because it has no
      console.log("Resolved", response);   // 'onRejected' argument
      return resolve(response);
    })
    .catch((err) => {                      // this will be called and the error
      console.log("CAUGHT ERROR", err);    // will be consumed so need to re-throw
      throw new Error('An unknown error occurred and has been reported.');
    });
}

Bearing in mind that a catch is just syntactic sugar for then(undefined, reject) and that, once rejected, a promise is no longer pending , calling it's then method will return undefined 'as soon as possible'.请记住, catch只是then(undefined, reject)语法糖,一旦被拒绝,promise 就不再是pending ,调用它的then方法将“尽快”返回undefined So you can chain another then after the catch if you prefer not to throw...因此,如果您不想扔掉,则可以在捕获后连接另一个...

this.createUser = function (data) {
  var query = "INSERT into users SET ?";

  return Container.DB.query(query, data)
    .then((response) => {                  // on error, skip this because it has no
      console.log("Resolved", response);   // 'onRejected' argument
      return resolve(response);
    })
    .catch((err) => {                      // this will be called and the error
      console.log("CAUGHT ERROR", err);    // will be consumed. The returned promise
    })                                     // state will be rejected but not pending
                                           // It's then method returns 'undefined' as 
                                           // soon as possible
    .then(() => 'An unknown error occurred and has been reported.');
}

Taking it one step further, bearing in mind that the value returned by a resolved or rejected promise is the return value of whichever of those is called, you can pass any value you like to the consumer via the return in the catch ...更进一步,请记住已解决或拒绝的承诺返回的值是其中任何一个被调用的返回值,您可以通过catchreturn将您喜欢的任何值传递给消费者......

this.createUser = function (data) {
  var query = "INSERT into users SET ?";

  return Container.DB.query(query, data)
    .then((response) => {                  // on error, skip this because it has no
      console.log("Resolved", response);   // 'onRejected' argument
      return resolve(response);
    })
    .catch((err) => {                      // this will be called and the error
      console.log("CAUGHT ERROR", err);    // will be consumed. The returned promise
                                           // state will be rejected but not pending
                                           // but you can still return any value
      return 'An unknown error occurred and has been reported.'
    })
}

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

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