From 292b9f06d8a55335ed6e76d5b8d110b098a5414e Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 11 May 2024 17:08:38 +0200 Subject: [PATCH] fix: show remote server response when its an error --- src/errors.rs | 12 +++++++++++- src/server/fetcher.rs | 14 +++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 8ec6e1ac..5c4183d6 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,4 +1,4 @@ -use axum::{http::StatusCode, response::Redirect}; +use axum::{http::StatusCode, response::{IntoResponse, Redirect}}; #[derive(Debug, thiserror::Error)] pub enum UpubError { @@ -20,6 +20,11 @@ pub enum UpubError { #[error("fetch error: {0}")] Reqwest(#[from] reqwest::Error), + // TODO this is quite ugly because its basically a reqwest::Error but with extra string... buuut + // helps with debugging! + #[error("fetch error: {0} -- server responded with {1}")] + FetchError(reqwest::Error, String), + #[error("invalid base64 string: {0}")] Base64(#[from] base64::DecodeError), @@ -74,6 +79,11 @@ impl axum::response::IntoResponse for UpubError { UpubError::Redirect(to) => Redirect::to(&to).into_response(), UpubError::Status(status) => (status, descr).into_response(), UpubError::Database(_) => (StatusCode::SERVICE_UNAVAILABLE, descr).into_response(), + UpubError::FetchError(e, body) => + ( + e.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), + format!("failed fetching '{}': {descr} -- server responded with {body}", e.url().map(|x| x.to_string()).unwrap_or_default()), + ).into_response(), UpubError::Reqwest(x) => ( x.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), diff --git a/src/server/fetcher.rs b/src/server/fetcher.rs index 87b41654..41029b11 100644 --- a/src/server/fetcher.rs +++ b/src/server/fetcher.rs @@ -5,7 +5,7 @@ use base64::Engine; use reqwest::{header::{ACCEPT, CONTENT_TYPE, USER_AGENT}, Method, Response}; use sea_orm::{sea_query::Expr, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter}; -use crate::{model, VERSION}; +use crate::{errors::UpubError, model, VERSION}; use super::{auth::HttpSignature, Context}; @@ -54,7 +54,7 @@ pub trait Fetcher { .build_manually(&method.to_string().to_lowercase(), &path, headers_map) .sign(key)?; - Ok(reqwest::Client::new() + let response = reqwest::Client::new() .request(method.clone(), url) .header(ACCEPT, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") .header(CONTENT_TYPE, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") @@ -65,9 +65,13 @@ pub trait Fetcher { .header("Signature", signer.header()) .body(payload.unwrap_or("").to_string()) .send() - .await? - .error_for_status()? - ) + .await?; + + // TODO this is ugly but i want to see the raw response text when it's a failure + match response.error_for_status_ref() { + Ok(_) => Ok(response), + Err(e) => Err(UpubError::FetchError(e, response.text().await?)), + } } }