better sync error messages (#1254)
This commit is contained in:
parent
fbed2862fd
commit
bdba88c11f
3 changed files with 49 additions and 19 deletions
|
@ -181,9 +181,19 @@ impl<'a> Client<'a> {
|
||||||
|
|
||||||
let resp = self.client.get(url).send().await?;
|
let resp = self.client.get(url).send().await?;
|
||||||
|
|
||||||
let history = resp.json::<SyncHistoryResponse>().await?;
|
let status = resp.status();
|
||||||
|
if status.is_success() {
|
||||||
Ok(history)
|
let history = resp.json::<SyncHistoryResponse>().await?;
|
||||||
|
Ok(history)
|
||||||
|
} else if status.is_client_error() {
|
||||||
|
let error = resp.json::<ErrorResponse>().await?.reason;
|
||||||
|
bail!("Could not fetch history: {error}.")
|
||||||
|
} else if status.is_server_error() {
|
||||||
|
let error = resp.json::<ErrorResponse>().await?.reason;
|
||||||
|
bail!("There was an error with the atuin sync service: {error}.\nIf the problem persists, contact the host")
|
||||||
|
} else {
|
||||||
|
bail!("There was an error with the atuin sync service: Status {status:?}.\nIf the problem persists, contact the host")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn post_history(&self, history: &[AddHistoryRequest]) -> Result<()> {
|
pub async fn post_history(&self, history: &[AddHistoryRequest]) -> Result<()> {
|
||||||
|
|
|
@ -63,10 +63,6 @@ pub async fn list<DB: Database>(
|
||||||
100
|
100
|
||||||
};
|
};
|
||||||
|
|
||||||
let history = db
|
|
||||||
.list_history(&user, req.sync_ts, req.history_ts, &req.host, page_size)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
if req.sync_ts.unix_timestamp_nanos() < 0 || req.history_ts.unix_timestamp_nanos() < 0 {
|
if req.sync_ts.unix_timestamp_nanos() < 0 || req.history_ts.unix_timestamp_nanos() < 0 {
|
||||||
error!("client asked for history from < epoch 0");
|
error!("client asked for history from < epoch 0");
|
||||||
return Err(
|
return Err(
|
||||||
|
@ -75,6 +71,10 @@ pub async fn list<DB: Database>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let history = db
|
||||||
|
.list_history(&user, req.sync_ts, req.history_ts, &req.host, page_size)
|
||||||
|
.await;
|
||||||
|
|
||||||
if let Err(e) = history {
|
if let Err(e) = history {
|
||||||
error!("failed to load history: {}", e);
|
error!("failed to load history: {}", e);
|
||||||
return Err(ErrorResponse::reply("failed to load history")
|
return Err(ErrorResponse::reply("failed to load history")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use atuin_common::api::ErrorResponse;
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::FromRequestParts,
|
extract::FromRequestParts,
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
|
@ -11,8 +12,11 @@ use tower::ServiceBuilder;
|
||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
|
|
||||||
use super::handlers;
|
use super::handlers;
|
||||||
use crate::settings::Settings;
|
use crate::{
|
||||||
use atuin_server_database::{models::User, Database};
|
handlers::{ErrorResponseStatus, RespExt},
|
||||||
|
settings::Settings,
|
||||||
|
};
|
||||||
|
use atuin_server_database::{models::User, Database, DbError};
|
||||||
|
|
||||||
pub struct UserAuth(pub User);
|
pub struct UserAuth(pub User);
|
||||||
|
|
||||||
|
@ -21,7 +25,7 @@ impl<DB: Send + Sync> FromRequestParts<AppState<DB>> for UserAuth
|
||||||
where
|
where
|
||||||
DB: Database,
|
DB: Database,
|
||||||
{
|
{
|
||||||
type Rejection = http::StatusCode;
|
type Rejection = ErrorResponseStatus<'static>;
|
||||||
|
|
||||||
async fn from_request_parts(
|
async fn from_request_parts(
|
||||||
req: &mut Parts,
|
req: &mut Parts,
|
||||||
|
@ -30,23 +34,39 @@ where
|
||||||
let auth_header = req
|
let auth_header = req
|
||||||
.headers
|
.headers
|
||||||
.get(http::header::AUTHORIZATION)
|
.get(http::header::AUTHORIZATION)
|
||||||
.ok_or(http::StatusCode::FORBIDDEN)?;
|
.ok_or_else(|| {
|
||||||
let auth_header = auth_header
|
ErrorResponse::reply("missing authorization header")
|
||||||
.to_str()
|
.with_status(http::StatusCode::BAD_REQUEST)
|
||||||
.map_err(|_| http::StatusCode::FORBIDDEN)?;
|
})?;
|
||||||
let (typ, token) = auth_header
|
let auth_header = auth_header.to_str().map_err(|_| {
|
||||||
.split_once(' ')
|
ErrorResponse::reply("invalid authorization header encoding")
|
||||||
.ok_or(http::StatusCode::FORBIDDEN)?;
|
.with_status(http::StatusCode::BAD_REQUEST)
|
||||||
|
})?;
|
||||||
|
let (typ, token) = auth_header.split_once(' ').ok_or_else(|| {
|
||||||
|
ErrorResponse::reply("invalid authorization header encoding")
|
||||||
|
.with_status(http::StatusCode::BAD_REQUEST)
|
||||||
|
})?;
|
||||||
|
|
||||||
if typ != "Token" {
|
if typ != "Token" {
|
||||||
return Err(http::StatusCode::FORBIDDEN);
|
return Err(
|
||||||
|
ErrorResponse::reply("invalid authorization header encoding")
|
||||||
|
.with_status(http::StatusCode::BAD_REQUEST),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = state
|
let user = state
|
||||||
.database
|
.database
|
||||||
.get_session_user(token)
|
.get_session_user(token)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| http::StatusCode::FORBIDDEN)?;
|
.map_err(|e| match e {
|
||||||
|
DbError::NotFound => ErrorResponse::reply("session not found")
|
||||||
|
.with_status(http::StatusCode::FORBIDDEN),
|
||||||
|
DbError::Other(e) => {
|
||||||
|
tracing::error!(error = ?e, "could not query user session");
|
||||||
|
ErrorResponse::reply("could not query user session")
|
||||||
|
.with_status(http::StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(UserAuth(user))
|
Ok(UserAuth(user))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue