fix: show remote server response when its an error

This commit is contained in:
əlemi 2024-05-11 17:08:38 +02:00
parent 5b22c0c33b
commit 292b9f06d8
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 20 additions and 6 deletions

View file

@ -1,4 +1,4 @@
use axum::{http::StatusCode, response::Redirect}; use axum::{http::StatusCode, response::{IntoResponse, Redirect}};
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum UpubError { pub enum UpubError {
@ -20,6 +20,11 @@ pub enum UpubError {
#[error("fetch error: {0}")] #[error("fetch error: {0}")]
Reqwest(#[from] reqwest::Error), 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}")] #[error("invalid base64 string: {0}")]
Base64(#[from] base64::DecodeError), Base64(#[from] base64::DecodeError),
@ -74,6 +79,11 @@ impl axum::response::IntoResponse for UpubError {
UpubError::Redirect(to) => Redirect::to(&to).into_response(), UpubError::Redirect(to) => Redirect::to(&to).into_response(),
UpubError::Status(status) => (status, descr).into_response(), UpubError::Status(status) => (status, descr).into_response(),
UpubError::Database(_) => (StatusCode::SERVICE_UNAVAILABLE, 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) => UpubError::Reqwest(x) =>
( (
x.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), x.status().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),

View file

@ -5,7 +5,7 @@ use base64::Engine;
use reqwest::{header::{ACCEPT, CONTENT_TYPE, USER_AGENT}, Method, Response}; use reqwest::{header::{ACCEPT, CONTENT_TYPE, USER_AGENT}, Method, Response};
use sea_orm::{sea_query::Expr, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter}; 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}; use super::{auth::HttpSignature, Context};
@ -54,7 +54,7 @@ pub trait Fetcher {
.build_manually(&method.to_string().to_lowercase(), &path, headers_map) .build_manually(&method.to_string().to_lowercase(), &path, headers_map)
.sign(key)?; .sign(key)?;
Ok(reqwest::Client::new() let response = reqwest::Client::new()
.request(method.clone(), url) .request(method.clone(), url)
.header(ACCEPT, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") .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\"") .header(CONTENT_TYPE, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
@ -65,9 +65,13 @@ pub trait Fetcher {
.header("Signature", signer.header()) .header("Signature", signer.header())
.body(payload.unwrap_or("").to_string()) .body(payload.unwrap_or("").to_string())
.send() .send()
.await? .await?;
.error_for_status()?
) // 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?)),
}
} }
} }