Use anyhow.

This commit is contained in:
LukeMathWalker 2021-05-12 09:08:38 +01:00
parent c6e88e8f8e
commit 4e04ade2ed
3 changed files with 17 additions and 20 deletions

1
Cargo.lock generated
View file

@ -2670,6 +2670,7 @@ dependencies = [
"actix-rt",
"actix-service",
"actix-web",
"anyhow",
"chrono",
"claim",
"config",

View file

@ -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"

View file

@ -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())
}