From c6e88e8f8ed63d28baf4687206c133f4849e713c Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Mon, 10 May 2021 09:57:49 +0100 Subject: [PATCH] Use thiserror. --- Cargo.lock | 1 + Cargo.toml | 1 + src/routes/subscriptions.rs | 76 +++++++------------------------------ 3 files changed, 15 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f456674..83806cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2685,6 +2685,7 @@ dependencies = [ "serde_json", "sha2", "sqlx", + "thiserror", "tokio", "tracing", "tracing-actix-web", diff --git a/Cargo.toml b/Cargo.toml index 3640aa5..855e49a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ tracing-futures = "0.2.4" tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] } tracing-bunyan-formatter = "0.2.2" tracing-log = "0.1.1" +thiserror = "1.0.24" serde-aux = "1.0.1" unicode-segmentation = "1.7.1" validator = "0.12.0" diff --git a/src/routes/subscriptions.rs b/src/routes/subscriptions.rs index b130154..2d0c702 100644 --- a/src/routes/subscriptions.rs +++ b/src/routes/subscriptions.rs @@ -26,56 +26,20 @@ impl TryInto for FormData { } } +#[derive(thiserror::Error)] pub enum SubscribeError { + #[error("{0}")] ValidationError(String), - PoolError(sqlx::Error), - InsertSubscriberError(sqlx::Error), - StoreTokenError(StoreTokenError), - TransactionCommitError(sqlx::Error), - SendEmailError(reqwest::Error), -} - -impl From for SubscribeError { - fn from(e: reqwest::Error) -> Self { - Self::SendEmailError(e) - } -} - -impl From for SubscribeError { - fn from(e: StoreTokenError) -> Self { - Self::StoreTokenError(e) - } -} - -impl From for SubscribeError { - fn from(e: String) -> Self { - Self::ValidationError(e) - } -} - -impl std::fmt::Display for SubscribeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - SubscribeError::ValidationError(e) => write!(f, "{}", e), - SubscribeError::PoolError(_) => { - write!(f, "Failed to acquire a Postgres connection from the pool") - } - SubscribeError::InsertSubscriberError(_) => { - write!(f, "Failed to insert new subscriber in the database.") - } - SubscribeError::StoreTokenError(_) => write!( - f, - "Failed to store the confirmation token for a new subscriber." - ), - SubscribeError::TransactionCommitError(_) => { - write!( - f, - "Failed to commit SQL transaction to store a new subscriber." - ) - } - SubscribeError::SendEmailError(_) => write!(f, "Failed to send a confirmation email."), - } - } + #[error("Failed to acquire a Postgres connection from the pool")] + PoolError(#[source] sqlx::Error), + #[error("Failed to insert new subscriber in the database.")] + InsertSubscriberError(#[source] sqlx::Error), + #[error("Failed to store the confirmation token for a new subscriber.")] + StoreTokenError(#[from] StoreTokenError), + #[error("Failed to commit SQL transaction to store a new subscriber.")] + TransactionCommitError(#[source] sqlx::Error), + #[error("Failed to send a confirmation email.")] + SendEmailError(#[from] reqwest::Error), } impl std::fmt::Debug for SubscribeError { @@ -84,20 +48,6 @@ impl std::fmt::Debug for SubscribeError { } } -impl std::error::Error for SubscribeError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - // &str does not implement `Error` - we consider it the root cause - SubscribeError::ValidationError(_) => None, - SubscribeError::PoolError(e) => Some(e), - SubscribeError::InsertSubscriberError(e) => Some(e), - SubscribeError::StoreTokenError(e) => Some(e), - SubscribeError::TransactionCommitError(e) => Some(e), - SubscribeError::SendEmailError(e) => Some(e), - } - } -} - impl ResponseError for SubscribeError { fn status_code(&self) -> StatusCode { match self { @@ -125,7 +75,7 @@ pub async fn subscribe( email_client: web::Data, base_url: web::Data, ) -> Result { - let new_subscriber = form.0.try_into()?; + let new_subscriber = form.0.try_into().map_err(SubscribeError::ValidationError)?; let mut transaction = pool.begin().await.map_err(SubscribeError::PoolError)?; let subscriber_id = insert_subscriber(&mut transaction, &new_subscriber) .await