diff --git a/atuin-client/src/api_client.rs b/atuin-client/src/api_client.rs index d0511f8..5692fea 100644 --- a/atuin-client/src/api_client.rs +++ b/atuin-client/src/api_client.rs @@ -9,7 +9,7 @@ use reqwest::{ use sodiumoxide::crypto::secretbox; use atuin_common::api::{ - AddHistoryRequest, CountResponse, LoginRequest, LoginResponse, RegisterResponse, + AddHistoryRequest, CountResponse, ErrorResponse, LoginRequest, LoginResponse, RegisterResponse, SyncHistoryResponse, }; @@ -58,7 +58,8 @@ pub async fn register( .await?; if !resp.status().is_success() { - bail!("failed to register user"); + let error = resp.json::().await?; + bail!("failed to register user: {}", error.reason); } let session = resp.json::().await?; @@ -77,7 +78,8 @@ pub async fn login(address: &str, req: LoginRequest) -> Result { .await?; if resp.status() != reqwest::StatusCode::OK { - bail!("invalid login details"); + let error = resp.json::().await?; + bail!("invalid login details: {}", error.reason); } let session = resp.json::().await?; diff --git a/atuin-common/src/api.rs b/atuin-common/src/api.rs index 47bbcde..ba04fd7 100644 --- a/atuin-common/src/api.rs +++ b/atuin-common/src/api.rs @@ -1,5 +1,6 @@ use chrono::Utc; use serde::{Deserialize, Serialize}; +use std::borrow::Cow; #[derive(Debug, Serialize, Deserialize)] pub struct UserResponse { @@ -53,3 +54,8 @@ pub struct SyncHistoryRequest { pub struct SyncHistoryResponse { pub history: Vec, } + +#[derive(Debug, Serialize, Deserialize)] +pub struct ErrorResponse<'a> { + pub reason: Cow<'a, str>, +} diff --git a/atuin-server/src/handlers/history.rs b/atuin-server/src/handlers/history.rs index 2b10790..d2fda77 100644 --- a/atuin-server/src/handlers/history.rs +++ b/atuin-server/src/handlers/history.rs @@ -7,7 +7,7 @@ use axum::{ use http::StatusCode; use tracing::{debug, error, instrument}; -use super::{ErrorResponse, ErrorResponseStatus}; +use super::{ErrorResponse, ErrorResponseStatus, RespExt}; use crate::{ calendar::{TimePeriod, TimePeriodInfo}, database::{Database, Postgres}, diff --git a/atuin-server/src/handlers/mod.rs b/atuin-server/src/handlers/mod.rs index 4aa7423..4be3e38 100644 --- a/atuin-server/src/handlers/mod.rs +++ b/atuin-server/src/handlers/mod.rs @@ -1,5 +1,4 @@ -use std::borrow::Cow; - +use atuin_common::api::ErrorResponse; use axum::{response::IntoResponse, Json}; use serde::{Deserialize, Serialize}; @@ -23,11 +22,6 @@ pub async fn index() -> Json { }) } -#[derive(Debug, Serialize, Deserialize)] -pub struct ErrorResponse<'a> { - pub reason: Cow<'a, str>, -} - impl<'a> IntoResponse for ErrorResponseStatus<'a> { fn into_response(self) -> axum::response::Response { (self.status, Json(self.error)).into_response() @@ -39,15 +33,20 @@ pub struct ErrorResponseStatus<'a> { pub status: http::StatusCode, } -impl<'a> ErrorResponse<'a> { - pub fn with_status(self, status: http::StatusCode) -> ErrorResponseStatus<'a> { +pub trait RespExt<'a> { + fn with_status(self, status: http::StatusCode) -> ErrorResponseStatus<'a>; + fn reply(reason: &'a str) -> Self; +} + +impl<'a> RespExt<'a> for ErrorResponse<'a> { + fn with_status(self, status: http::StatusCode) -> ErrorResponseStatus<'a> { ErrorResponseStatus { error: self, status, } } - pub fn reply(reason: &'a str) -> ErrorResponse { + fn reply(reason: &'a str) -> ErrorResponse { Self { reason: reason.into(), } diff --git a/atuin-server/src/handlers/user.rs b/atuin-server/src/handlers/user.rs index 42e2b5c..1bc9178 100644 --- a/atuin-server/src/handlers/user.rs +++ b/atuin-server/src/handlers/user.rs @@ -6,7 +6,7 @@ use sodiumoxide::crypto::pwhash::argon2id13; use tracing::{debug, error, instrument}; use uuid::Uuid; -use super::{ErrorResponse, ErrorResponseStatus}; +use super::{ErrorResponse, ErrorResponseStatus, RespExt}; use crate::{ database::{Database, Postgres}, models::{NewSession, NewUser},