diff --git a/src/crypto/store/mod.rs b/src/crypto/store/mod.rs index 5a09928e..878ac5ba 100644 --- a/src/crypto/store/mod.rs +++ b/src/crypto/store/mod.rs @@ -1,14 +1,37 @@ -use std::io::Result; +use std::io::Error as IoError; use std::sync::Arc; +use url::ParseError; use async_trait::async_trait; +use thiserror::Error; use tokio::sync::Mutex; use super::olm::Account; +use olm_rs::errors::OlmAccountError; #[cfg(feature = "sqlite-cryptostore")] pub mod sqlite; +#[cfg(feature = "sqlite-cryptostore")] +use sqlx::Error as SqlxError; + +#[derive(Error, Debug)] +pub enum CryptoStoreError { + #[error("can't read or write from the store")] + Io(#[from] IoError), + #[error("Olm operation failed")] + OlmAccountError(#[from] OlmAccountError), + #[error("URL can't be parsed")] + UrlParse(#[from] ParseError), + // TODO flatten the SqlxError to make it easier for other store + // implementations. + #[cfg(feature = "sqlite-cryptostore")] + #[error("database error")] + DatabaseError(#[from] SqlxError), +} + +pub type Result = std::result::Result; + #[async_trait] pub trait CryptoStore { async fn load_account(&self) -> Result; diff --git a/src/crypto/store/sqlite.rs b/src/crypto/store/sqlite.rs index 211075cb..b411ec0f 100644 --- a/src/crypto/store/sqlite.rs +++ b/src/crypto/store/sqlite.rs @@ -46,11 +46,9 @@ impl SqliteStore { } fn path_to_url>(path: P) -> Result { - let url = Url::from_directory_path(path.as_ref()).expect("Can't create URL from directory"); - let url = url - .join(DATABASE_NAME) - .expect("Can't append database name to URL"); - Ok(url) + // TODO this returns an empty error if the path isn't absolute. + let url = Url::from_directory_path(path.as_ref()).expect("Invalid path"); + Ok(url.join(DATABASE_NAME)?) } async fn open_helper( @@ -85,8 +83,7 @@ impl SqliteStore { ); "#, ) - .await - .unwrap(); + .await?; Ok(()) } @@ -113,10 +110,13 @@ impl CryptoStore for SqliteStore { .bind(&*self.user_id) .bind(&*self.device_id) .fetch_one(&mut *connection) - .await - .unwrap(); + .await?; - Ok(Account::from_pickle(pickle, self.get_pickle_mode(), shared).unwrap()) + Ok(Account::from_pickle( + pickle, + self.get_pickle_mode(), + shared, + )?) } async fn save_account(&self, account: Arc>) -> Result<()> { @@ -134,8 +134,7 @@ impl CryptoStore for SqliteStore { .bind(&pickle) .bind(acc.shared) .execute(&mut *connection) - .await - .unwrap(); + .await?; query( "UPDATE account @@ -149,8 +148,7 @@ impl CryptoStore for SqliteStore { .bind(&*self.user_id) .bind(&*self.device_id) .execute(&mut *connection) - .await - .unwrap(); + .await?; Ok(()) }