在knex事务中抛出自定义错误会导致api崩溃

我目前正在与knex工作在API。 我必须在一个大事务中执行一些操作,并且必须在那里进行判断 – 如果任何validation返回“false” – 事务必须停止。 问题是,每当我抛出“我的”错误,即使所有的“Catch”ES都得到它,并且res被正确地发送 – 之后,我的整个api崩溃了:

无法读取null的属性“removeListener”

这很奇怪,因为没有类似的问题来捕捉由knex本身造成的错误。

Strangley,如果我会删除我的错误抛出 – 我仍然会得到未处理的exception

无法读取null的属性“回滚”

在代码中看起来像这样:

f1(){ // (...) let noErrors = true; return global.knex .transaction((trx) => { return operation1(trx) //Knex operation returning object with parameter "correct" .then((output)=>{ if(output.correct === false) throw new Error('CustomError'); }) .then(()=>{ return operation2(trx); }) .then(()=>{ return operation3(trx); }) // (...) .then(trx.commit) .catch((error) => { console.error('TRANS. FAILED'); noErrors = false; trx.rollback(); throw error; // Both with and without it - failed }); }) .then(() => { console.log('TRANS. OK'); }) .then(() => { if(noErrors) return {result:'MyResultsHere'}; else return {result:'ErrorOccured'}; }) .catch((error) => { return {result:'ErrorOccuredAgain'}; }); 

}

然后这个函数的结果(promise)被返回:

  f1().then((output)=>{ console.log(output.result); // (...) sending response for request here } .catch((err) => { console.error(err); res.status(500).send(); }); 

还有一些额外的testing – 看来我可以抛出我的自定义错误,但这里的问题是与回滚 – 和soemtie我得到一个更多的错误:

TransactionError:请求只能在LoggedIn状态下进行,而不能在SentClientRequest状态下进行

看起来你正在混合两种不同的事务处理语法(下面的简单例子):

 knex.transaction(trx => { // returning promise automatically calls commit / rollback return operation(1); }) .then(results => console.log("commit was called automatically", results)) .catch(err => console.log("rollback was called automatically", err)) 

 knex.transaction(trx => { // NOT returning promise so you need to call commit / rollback explicitly operation(1).then(results => trx.commit(results)) .catch(err => trx.rollback(err)); }) .then(results => console.log("stuff from transaction commit", results)) .catch(err => console.log("error passed to rollback", err)) 

您可能正在尝试这样做:

 f1(){ // (...) return global.knex .transaction(trx => { return operation1(trx) .then(output => { if(output.correct === false) { // if wrong results promise will reject with "CustomError" throw new Error('CustomError'); } }) .then(() => operation2(trx)) .then(() => operation3(trx)) // (...) ; }) .then(resultsOfLastThen => { console.log('TRANS. OK', resultsOfLastOperation); return { result: 'MyResultsHere' }; }) .catch(error => { return { result: 'ErrorOccured' }; }); }