节点mysql错误不被Promise拒绝

我正在做一个简单的数据库调用包装在一个承诺,并试图捕捉错误,并通过它的承诺reject(),但拒绝不被处理或由呼叫代码冒泡备份。 当mysql调用失败时,代码停止执行。

mysqlcallback中的错误是:

拒绝QUERY {错误:您的SQL语法错误; 检查对应于您的MariaDB服务器版本的手册,在“?”附近使用正确的语法。 在第1行

这里是数据库查询代码:

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); }); }); } 

这里是调用代码:

 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); }); }); } 

我在数据库查询代码中得到了“拒绝QUERY”,但是在调用代码中没有任何东西(即.then,error handling程序或.catch处理程序)。 是否有可能得到的MySQL错误,以达到这些点的代码,所以我可以响应用户? 难道我做错了什么?

@JaromandaX提到的反模式迫使你不必要地通过燃烧的箍跳跃,以适应它…和你被烧毁。

但是,首先,你是在catch之前拒绝外部的(多余的)诺言,这样catch了。 在承诺链中抛出一个错误之后,第一个第二个参数( onRejected )可以被消耗,所以它不会被传播。 但是,无论如何,你需要把错误归咎于你拒绝的外在诺言。

 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.'; }); ; } 

更糟的是,你可以login并重新抛出错误在一个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.'); }); }) ; } 

更好的办法是消除反模式,并在(冗余)promise包装器上用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.'); }); } 

记住catch只是语法上的糖then(undefined, reject) ,一旦被拒绝,promise就不再等待 ,调用它, then方法会尽快返回undefined 。 所以你可以链接另一个然后赶上,如果你不想扔…

 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.'); } 

更进一步,请记住,解决或拒绝的承诺所返回的值是所调用的返回值,您可以通过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.' }) }