I would like to save entity in database in case of some specific errors and it seems nice to use custom result enum for this which should rethrow Err and SaveOnErr when ? is used.
I’ve tried to copy FromResidual trait from Result which seems responsible for ? usage, but was unsuccessful, is it possible to do?
#[derive(Copy, PartialEq, Eq, Debug, Clone)]
pub enum SavableResult<T, E> {
Ok(T),
Err(E),
SaveOnErr(E),
}
fn test1() {
let result = test2();
match result {
SavableResult::Ok(_) | SavableResult::SaveOnErr(_) => save(),
SavableResult::Err(_) => {}
};
}
fn test2() -> SavableResult<(), ApiErr> {
test3()?; // not working
SavableResult::Ok(())
}
fn test3() -> SavableResult<(), ApiErr> {
SavableResult::Ok(())
}
fn save() {
// save in db
}
Specific issue that I want to solve:
pub async fn execute(&self) -> Result<JwtTokensPair, ApiErr> {
let mut auth = AuthRepository::get_by_user_id(user_id, &trx).await?;
// in case of incorrect password `auth` entity `failed_auth_count`
// is incremented and I need to save it in database anyway
// to block any auth after 10 fails for hour
// but only for one specific error
let result = auth.login(&self.password, self.hash_service);
// problem here is that it's easy to forget which
// entities have this special requirement
// or use this ugly match everywhere
match result {
Ok(_)
| Err(ApiErr {
save_on_err: true, ..
}) => AuthRepository::save(&auth, &trx).await?,
Err(_) => {}
};
trx.commit().await?;
result
}
>Solution :
According to the documentation, you cannot overload the ? operator at this time. Perhaps you could write some sort of conversion that takes your values to a Result<T, E>.