mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2025-01-19 05:25:37 +00:00
Use anyhow.
This commit is contained in:
parent
c6e88e8f8e
commit
4e04ade2ed
3 changed files with 17 additions and 20 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2670,6 +2670,7 @@ dependencies = [
|
|||
"actix-rt",
|
||||
"actix-service",
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"claim",
|
||||
"config",
|
||||
|
|
|
@ -35,6 +35,7 @@ validator = "0.12.0"
|
|||
rand = { version = "0.8", features=["std_rng"] }
|
||||
sha2 = { version = "0.9" }
|
||||
tracing-actix-web = "0.4.0-beta.4"
|
||||
anyhow = "1.0.40"
|
||||
|
||||
[dev-dependencies]
|
||||
once_cell = "1.7.2"
|
||||
|
|
|
@ -3,6 +3,7 @@ use crate::email_client::EmailClient;
|
|||
use crate::startup::ApplicationBaseUrl;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::{web, HttpResponse, ResponseError};
|
||||
use anyhow::Context;
|
||||
use chrono::Utc;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
@ -30,16 +31,8 @@ impl TryInto<NewSubscriber> for FormData {
|
|||
pub enum SubscribeError {
|
||||
#[error("{0}")]
|
||||
ValidationError(String),
|
||||
#[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),
|
||||
#[error(transparent)]
|
||||
UnexpectedError(#[from] anyhow::Error),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for SubscribeError {
|
||||
|
@ -52,11 +45,7 @@ impl ResponseError for SubscribeError {
|
|||
fn status_code(&self) -> StatusCode {
|
||||
match self {
|
||||
SubscribeError::ValidationError(_) => StatusCode::BAD_REQUEST,
|
||||
SubscribeError::PoolError(_)
|
||||
| SubscribeError::TransactionCommitError(_)
|
||||
| SubscribeError::InsertSubscriberError(_)
|
||||
| SubscribeError::StoreTokenError(_)
|
||||
| SubscribeError::SendEmailError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
SubscribeError::UnexpectedError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,23 +65,29 @@ pub async fn subscribe(
|
|||
base_url: web::Data<ApplicationBaseUrl>,
|
||||
) -> Result<HttpResponse, SubscribeError> {
|
||||
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
|
||||
.context("Failed to acquire a Postgres connection from the pool")?;
|
||||
let subscriber_id = insert_subscriber(&mut transaction, &new_subscriber)
|
||||
.await
|
||||
.map_err(SubscribeError::InsertSubscriberError)?;
|
||||
.context("Failed to insert new subscriber in the database.")?;
|
||||
let subscription_token = generate_subscription_token();
|
||||
store_token(&mut transaction, subscriber_id, &subscription_token).await?;
|
||||
store_token(&mut transaction, subscriber_id, &subscription_token)
|
||||
.await
|
||||
.context("Failed to store the confirmation token for a new subscriber.")?;
|
||||
transaction
|
||||
.commit()
|
||||
.await
|
||||
.map_err(SubscribeError::TransactionCommitError)?;
|
||||
.context("Failed to commit SQL transaction to store a new subscriber.")?;
|
||||
send_confirmation_email(
|
||||
&email_client,
|
||||
new_subscriber,
|
||||
&base_url.0,
|
||||
&subscription_token,
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
.context("Failed to send a confirmation email.")?;
|
||||
Ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue