mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2025-06-05 23:18:57 +00:00
Refactor error handling for confirm
handler.
This commit is contained in:
parent
2b3dae3a6a
commit
7b64134fe7
2 changed files with 36 additions and 15 deletions
|
@ -196,7 +196,7 @@ impl std::fmt::Display for StoreTokenError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_chain_fmt(
|
pub fn error_chain_fmt(
|
||||||
e: &impl std::error::Error,
|
e: &impl std::error::Error,
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use actix_web::{web, HttpResponse};
|
use crate::routes::error_chain_fmt;
|
||||||
|
use actix_web::http::StatusCode;
|
||||||
|
use actix_web::{web, HttpResponse, ResponseError};
|
||||||
|
use anyhow::Context;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -7,24 +10,42 @@ pub struct Parameters {
|
||||||
subscription_token: String,
|
subscription_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error)]
|
||||||
|
pub enum ConfirmationError {
|
||||||
|
#[error(transparent)]
|
||||||
|
UnexpectedError(#[from] anyhow::Error),
|
||||||
|
#[error("There is no subscriber associated with the provided token.")]
|
||||||
|
UnknownToken,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for ConfirmationError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
error_chain_fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponseError for ConfirmationError {
|
||||||
|
fn status_code(&self) -> StatusCode {
|
||||||
|
match self {
|
||||||
|
Self::UnknownToken => StatusCode::UNAUTHORIZED,
|
||||||
|
Self::UnexpectedError(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(name = "Confirm a pending subscriber", skip(parameters, pool))]
|
#[tracing::instrument(name = "Confirm a pending subscriber", skip(parameters, pool))]
|
||||||
pub async fn confirm(
|
pub async fn confirm(
|
||||||
parameters: web::Query<Parameters>,
|
parameters: web::Query<Parameters>,
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
) -> Result<HttpResponse, HttpResponse> {
|
) -> Result<HttpResponse, ConfirmationError> {
|
||||||
let id = get_subscriber_id_from_token(&pool, ¶meters.subscription_token)
|
let subscriber_id = get_subscriber_id_from_token(&pool, ¶meters.subscription_token)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| HttpResponse::InternalServerError().finish())?;
|
.context("Failed to retrieve the subscriber id associated with the provided token.")?
|
||||||
match id {
|
.ok_or(ConfirmationError::UnknownToken)?;
|
||||||
// Non-existing token!
|
confirm_subscriber(&pool, subscriber_id)
|
||||||
None => Err(HttpResponse::Unauthorized().finish()),
|
.await
|
||||||
Some(subscriber_id) => {
|
.context("Failed to update the subscriber status to `confirmed`.")?;
|
||||||
confirm_subscriber(&pool, subscriber_id)
|
Ok(HttpResponse::Ok().finish())
|
||||||
.await
|
|
||||||
.map_err(|_| HttpResponse::InternalServerError().finish())?;
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(name = "Mark subscriber as confirmed", skip(subscriber_id, pool))]
|
#[tracing::instrument(name = "Mark subscriber as confirmed", skip(subscriber_id, pool))]
|
||||||
|
|
Loading…
Reference in a new issue