2017-01-23 55 views
1

我目前正在使用knex進行api工作。我必須在一個大事務中執行一些操作,並且必須在那裏進行判斷 - 如果任何驗證返回「false」 - 事務必須停止。問題是,每當我折騰「我的」的錯誤,即使所有的「捕捉」 ES把它買走,RES是sended corrently-權後,我的整個API崩潰,出現錯誤:在knex事務中拋出自定義錯誤導致api崩潰

Cannot read property "removeListener" of null

這是奇怪的,becouse有與由knex本身引起的捕獲錯誤沒有類似的問題。

Strangley,如果我想刪除我的錯誤投擲 - 我仍然會得到未處理的異常

Cannot read property "rollback" of 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'}; 
     }); 

}

此函數的結果(承諾)然後返回:

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

經過一番additiona ltesting - 它似乎liek我可以把我的自定義錯誤,但這裏的問題是與回退 - 並soemtiems我得到一個更多的錯誤:

TransactionError: Requests can only be made in the LoggedIn state, not the SentClientRequest state

回答

1

看起來你混合2個不同的事務處理語法(下面簡單的例子):

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