mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2025-01-31 11:02:29 +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,
|
||||
f: &mut std::fmt::Formatter<'_>,
|
||||
) -> 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 uuid::Uuid;
|
||||
|
||||
|
@ -7,25 +10,43 @@ pub struct Parameters {
|
|||
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))]
|
||||
pub async fn confirm(
|
||||
parameters: web::Query<Parameters>,
|
||||
pool: web::Data<PgPool>,
|
||||
) -> Result<HttpResponse, HttpResponse> {
|
||||
let id = get_subscriber_id_from_token(&pool, ¶meters.subscription_token)
|
||||
) -> Result<HttpResponse, ConfirmationError> {
|
||||
let subscriber_id = get_subscriber_id_from_token(&pool, ¶meters.subscription_token)
|
||||
.await
|
||||
.map_err(|_| HttpResponse::InternalServerError().finish())?;
|
||||
match id {
|
||||
// Non-existing token!
|
||||
None => Err(HttpResponse::Unauthorized().finish()),
|
||||
Some(subscriber_id) => {
|
||||
.context("Failed to retrieve the subscriber id associated with the provided token.")?
|
||||
.ok_or(ConfirmationError::UnknownToken)?;
|
||||
confirm_subscriber(&pool, subscriber_id)
|
||||
.await
|
||||
.map_err(|_| HttpResponse::InternalServerError().finish())?;
|
||||
.context("Failed to update the subscriber status to `confirmed`.")?;
|
||||
Ok(HttpResponse::Ok().finish())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(name = "Mark subscriber as confirmed", skip(subscriber_id, pool))]
|
||||
pub async fn confirm_subscriber(pool: &PgPool, subscriber_id: Uuid) -> Result<(), sqlx::Error> {
|
||||
|
|
Loading…
Reference in a new issue