Prevent panics when remote datastore transactions fail to start

This commit is contained in:
Tobie Morgan Hitchcock 2022-08-29 13:20:30 +01:00
parent cdf244f0f5
commit b9fc84bf18
2 changed files with 64 additions and 47 deletions

View file

@ -79,8 +79,7 @@ impl<'a> Executor<'a> {
async fn cancel(&mut self, local: bool) {
if local {
match self.txn.as_ref() {
Some(txn) => {
if let Some(txn) = self.txn.as_ref() {
let txn = txn.clone();
let mut txn = txn.lock().await;
if txn.cancel().await.is_err() {
@ -88,8 +87,6 @@ impl<'a> Executor<'a> {
}
self.txn = None;
}
None => unreachable!(),
}
}
}
@ -212,6 +209,12 @@ impl<'a> Executor<'a> {
Statement::Set(stm) => {
// Create a transaction
let loc = self.begin(stm.writeable()).await;
// Check the transaction
match self.err {
// We failed to create a transaction
true => Err(Error::TxFailure),
// The transaction began successfully
false => {
// Process the statement
match stm.compute(&ctx, &opt, &self.txn(), None).await {
Ok(val) => {
@ -227,6 +230,8 @@ impl<'a> Executor<'a> {
// Return nothing
Ok(Value::None)
}
}
}
// Process all other normal statements
_ => match self.err {
// This transaction has failed
@ -235,6 +240,12 @@ impl<'a> Executor<'a> {
false => {
// Create a transaction
let loc = self.begin(stm.writeable()).await;
// Check the transaction
match self.err {
// We failed to create a transaction
true => Err(Error::TxFailure),
// The transaction began successfully
false => {
// Process the statement
let res = match stm.timeout() {
// There is a timeout clause
@ -264,6 +275,8 @@ impl<'a> Executor<'a> {
// Return the result
res
}
}
}
},
};
// Get the statement end time

View file

@ -21,6 +21,10 @@ pub enum Error {
#[error("There was a problem with a datastore transaction: {0}")]
Tx(String),
/// There was an error when starting a new datastore transaction
#[error("There was an error when starting a new datastore transaction")]
TxFailure,
/// The transaction was already cancelled or committed
#[error("Couldn't update a finished transaction")]
TxFinished,