我正在做一个包含在promise中的简单数据库调用,并试图捕获错误并将其传递给promise reject(),但拒绝不会被调用代码处理或冒泡回来。当mysql调用失败时,代码就会停止执行。
mysql回调中的错误是:
REJECTING 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);
});
});
}
我在数据库查询代码中得到“REJECTING QUERY”,但是没有到达调用代码(即.then,或错误处理程序或.catch处理程序)。 是否有可能让mysql错误在代码中达到这些点,以便我可以响应用户?我做错了吗?
答案 0 :(得分:1)
@JaromandaX提到的反模式迫使你不必要地跳过燃烧的箍以适应它......并且你被烧伤了。
但是,首先,你在then
之前拒绝来自catch
的外部(冗余)承诺,因此catch
被绕过。在一个promise链中抛出一个错误后,带有第二个参数的第一个 thenable ( 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.';
});
;
}
更糟糕的是,您可以在一个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.');
});
})
;
}
更好的是,消除反模式,并在(冗余)承诺包装器上使用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)
的语法糖,一旦被拒绝,承诺就不再是待定,称之为then
{ {1}}方法会尽快返回undefined
&#39;。所以如果你不想抛出那么你可以在捕获之后链接另一个...
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.');
}
更进一步,请记住,已解决或拒绝的承诺返回的值是调用的那些值的返回值,您可以通过return
将您喜欢的任何值传递给消费者在catch
...
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.'
})
}