mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2025-02-07 14:32:21 +00:00
Use thiserror.
This commit is contained in:
parent
f0aee87a00
commit
c6e88e8f8e
3 changed files with 15 additions and 63 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2685,6 +2685,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-actix-web",
|
"tracing-actix-web",
|
||||||
|
|
|
@ -28,6 +28,7 @@ tracing-futures = "0.2.4"
|
||||||
tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] }
|
tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] }
|
||||||
tracing-bunyan-formatter = "0.2.2"
|
tracing-bunyan-formatter = "0.2.2"
|
||||||
tracing-log = "0.1.1"
|
tracing-log = "0.1.1"
|
||||||
|
thiserror = "1.0.24"
|
||||||
serde-aux = "1.0.1"
|
serde-aux = "1.0.1"
|
||||||
unicode-segmentation = "1.7.1"
|
unicode-segmentation = "1.7.1"
|
||||||
validator = "0.12.0"
|
validator = "0.12.0"
|
||||||
|
|
|
@ -26,56 +26,20 @@ impl TryInto<NewSubscriber> for FormData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error)]
|
||||||
pub enum SubscribeError {
|
pub enum SubscribeError {
|
||||||
|
#[error("{0}")]
|
||||||
ValidationError(String),
|
ValidationError(String),
|
||||||
PoolError(sqlx::Error),
|
#[error("Failed to acquire a Postgres connection from the pool")]
|
||||||
InsertSubscriberError(sqlx::Error),
|
PoolError(#[source] sqlx::Error),
|
||||||
StoreTokenError(StoreTokenError),
|
#[error("Failed to insert new subscriber in the database.")]
|
||||||
TransactionCommitError(sqlx::Error),
|
InsertSubscriberError(#[source] sqlx::Error),
|
||||||
SendEmailError(reqwest::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.")]
|
||||||
impl From<reqwest::Error> for SubscribeError {
|
TransactionCommitError(#[source] sqlx::Error),
|
||||||
fn from(e: reqwest::Error) -> Self {
|
#[error("Failed to send a confirmation email.")]
|
||||||
Self::SendEmailError(e)
|
SendEmailError(#[from] reqwest::Error),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StoreTokenError> for SubscribeError {
|
|
||||||
fn from(e: StoreTokenError) -> Self {
|
|
||||||
Self::StoreTokenError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> 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."),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for SubscribeError {
|
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 {
|
impl ResponseError for SubscribeError {
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
match self {
|
match self {
|
||||||
|
@ -125,7 +75,7 @@ pub async fn subscribe(
|
||||||
email_client: web::Data<EmailClient>,
|
email_client: web::Data<EmailClient>,
|
||||||
base_url: web::Data<ApplicationBaseUrl>,
|
base_url: web::Data<ApplicationBaseUrl>,
|
||||||
) -> Result<HttpResponse, SubscribeError> {
|
) -> Result<HttpResponse, SubscribeError> {
|
||||||
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 mut transaction = pool.begin().await.map_err(SubscribeError::PoolError)?;
|
||||||
let subscriber_id = insert_subscriber(&mut transaction, &new_subscriber)
|
let subscriber_id = insert_subscriber(&mut transaction, &new_subscriber)
|
||||||
.await
|
.await
|
||||||
|
|
Loading…
Reference in a new issue