diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs index 4e04c94a..1802357a 100644 --- a/src/admin/debug/commands.rs +++ b/src/admin/debug/commands.rs @@ -7,7 +7,7 @@ use std::{ use api::client::validate_and_add_event_id; use conduit::{ - debug, info, log, + debug, debug_error, err, info, log, log::{capture, Capture}, utils, warn, Error, PduEvent, Result, }; @@ -575,8 +575,8 @@ pub(super) async fn force_set_room_state_from_server( }; let pdu = PduEvent::from_id_val(&event_id, value.clone()).map_err(|e| { - warn!("Invalid PDU in fetching remote room state PDUs response: {} {:?}", e, value); - Error::BadServerResponse("Invalid PDU in send_join response.") + debug_error!("Invalid PDU in fetching remote room state PDUs response: {value:#?}"); + err!(BadServerResponse(debug_error!("Invalid PDU in send_join response: {e:?}"))) })?; self.services diff --git a/src/api/client/keys.rs b/src/api/client/keys.rs index 6fa7a8ad..a426364a 100644 --- a/src/api/client/keys.rs +++ b/src/api/client/keys.rs @@ -4,7 +4,7 @@ use std::{ }; use axum::extract::State; -use conduit::{debug, utils, utils::math::continue_exponential_backoff_secs, Error, Result}; +use conduit::{utils, utils::math::continue_exponential_backoff_secs, Err, Error, Result}; use futures_util::{stream::FuturesUnordered, StreamExt}; use ruma::{ api::{ @@ -362,8 +362,7 @@ pub(crate) async fn get_keys_helper bool + Send>( const MIN: u64 = 5 * 60; const MAX: u64 = 60 * 60 * 24; if continue_exponential_backoff_secs(MIN, MAX, time.elapsed(), *tries) { - debug!("Backing off query from {server:?}"); - return (server, Err(Error::BadServerResponse("bad query, still backing off"))); + return (server, Err!(BadServerResponse("bad query from {server:?}, still backing off"))); } } diff --git a/src/api/client/media.rs b/src/api/client/media.rs index 5c83c17f..bce9b2b5 100644 --- a/src/api/client/media.rs +++ b/src/api/client/media.rs @@ -5,13 +5,13 @@ use std::time::Duration; use axum::extract::State; use axum_client_ip::InsecureClientIp; use conduit::{ - debug_warn, error, + debug_warn, err, error, utils::{ self, content_disposition::{content_disposition_type, make_content_disposition, sanitise_filename}, math::ruma_from_usize, }, - warn, Error, Result, + warn, Err, Error, Result, }; use ruma::api::client::{ error::{ErrorKind, RetryAfter}, @@ -70,8 +70,9 @@ pub(crate) async fn get_media_preview_route( let url = &body.url; if !services.media.url_preview_allowed(url) { - warn!(%sender_user, "URL is not allowed to be previewed: {url}"); - return Err(Error::BadRequest(ErrorKind::forbidden(), "URL is not allowed to be previewed")); + return Err!(Request(Forbidden( + warn!(%sender_user, %url, "URL is not allowed to be previewed") + ))); } match services.media.get_url_preview(url).await { @@ -90,7 +91,6 @@ pub(crate) async fn get_media_preview_route( }, Err(e) => { warn!(%sender_user, "Failed to generate a URL preview: {e}"); - // there doesn't seem to be an agreed-upon error code in the spec. // the only response codes in the preview_url spec page are 200 and 429. Err(Error::BadRequest( @@ -222,10 +222,7 @@ pub(crate) async fn get_content_route( body.timeout_ms, ) .await - .map_err(|e| { - debug_warn!("Fetching media `{}` failed: {:?}", mxc, e); - Error::BadRequest(ErrorKind::NotFound, "Remote media error.") - })?; + .map_err(|e| err!(Request(NotFound(debug_warn!("Fetching media `{mxc}` failed: {e:?}")))))?; let content_disposition = Some(make_content_disposition( &response.content_type, @@ -241,7 +238,7 @@ pub(crate) async fn get_content_route( cache_control: Some(CACHE_CONTROL_IMMUTABLE.to_owned()), }) } else { - Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")) + Err!(Request(NotFound("Media not found."))) } } @@ -328,13 +325,10 @@ pub(crate) async fn get_content_as_filename_route( cache_control: Some(CACHE_CONTROL_IMMUTABLE.into()), }) }, - Err(e) => { - debug_warn!("Fetching media `{}` failed: {:?}", mxc, e); - Err(Error::BadRequest(ErrorKind::NotFound, "Remote media error.")) - }, + Err(e) => Err!(Request(NotFound(debug_warn!("Fetching media `{mxc}` failed: {e:?}")))), } } else { - Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")) + Err!(Request(NotFound("Media not found."))) } } @@ -385,10 +379,10 @@ pub(crate) async fn get_content_thumbnail_route( &mxc, body.width .try_into() - .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Width is invalid."))?, + .map_err(|e| err!(Request(InvalidParam("Width is invalid: {e:?}"))))?, body.height .try_into() - .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Height is invalid."))?, + .map_err(|e| err!(Request(InvalidParam("Height is invalid: {e:?}"))))?, ) .await? { @@ -411,7 +405,7 @@ pub(crate) async fn get_content_thumbnail_route( // we'll lie to the client and say the blocked server's media was not found and // log. the client has no way of telling anyways so this is a security bonus. debug_warn!("Received request for media `{}` on blocklisted server", mxc); - return Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")); + return Err!(Request(NotFound("Media not found."))); } match services @@ -460,13 +454,10 @@ pub(crate) async fn get_content_thumbnail_route( content_disposition, }) }, - Err(e) => { - debug_warn!("Fetching media `{}` failed: {:?}", mxc, e); - Err(Error::BadRequest(ErrorKind::NotFound, "Remote media error.")) - }, + Err(e) => Err!(Request(NotFound(debug_warn!("Fetching media `{mxc}` failed: {e:?}")))), } } else { - Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")) + Err!(Request(NotFound("Media not found."))) } } @@ -504,7 +495,7 @@ async fn get_remote_content( // we'll lie to the client and say the blocked server's media was not found and // log. the client has no way of telling anyways so this is a security bonus. debug_warn!("Received request for media `{mxc}` on blocklisted server"); - return Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")); + return Err!(Request(NotFound("Media not found."))); } let content_response = services diff --git a/src/api/client/membership.rs b/src/api/client/membership.rs index f0d2848f..4b27d8e3 100644 --- a/src/api/client/membership.rs +++ b/src/api/client/membership.rs @@ -8,11 +8,11 @@ use std::{ use axum::extract::State; use axum_client_ip::InsecureClientIp; use conduit::{ - debug, debug_warn, error, info, + debug, debug_error, debug_warn, err, error, info, pdu::{gen_event_id_canonical_json, PduBuilder}, trace, utils, utils::math::continue_exponential_backoff_secs, - warn, Error, PduEvent, Result, + warn, Err, Error, PduEvent, Result, }; use ruma::{ api::{ @@ -705,11 +705,11 @@ async fn join_room_by_id_helper_remote( { room_version }, - _ => return Err(Error::BadServerResponse("Room version is not supported")), + _ => return Err!(BadServerResponse("Room version is not supported")), }; let mut join_event_stub: CanonicalJsonObject = serde_json::from_str(make_join_response.event.get()) - .map_err(|_| Error::BadServerResponse("Invalid make_join event json received from server."))?; + .map_err(|e| err!(BadServerResponse("Invalid make_join event json received from server: {e:?}")))?; let join_authorized_via_users_server = join_event_stub .get("content") @@ -876,7 +876,7 @@ async fn join_room_by_id_helper_remote( info!("Parsing join event"); let parsed_join_pdu = PduEvent::from_id_val(event_id, join_event.clone()) - .map_err(|_| Error::BadServerResponse("Invalid join event PDU."))?; + .map_err(|e| err!(BadServerResponse("Invalid join event PDU: {e:?}")))?; let mut state = HashMap::new(); let pub_key_map = RwLock::new(BTreeMap::new()); @@ -899,8 +899,8 @@ async fn join_room_by_id_helper_remote( }; let pdu = PduEvent::from_id_val(&event_id, value.clone()).map_err(|e| { - warn!("Invalid PDU in send_join response: {} {:?}", e, value); - Error::BadServerResponse("Invalid PDU in send_join response.") + debug_warn!("Invalid PDU in send_join response: {value:#?}"); + err!(BadServerResponse("Invalid PDU in send_join response: {e:?}")) })?; services.rooms.outlier.add_pdu_outlier(&event_id, &value)?; @@ -1122,10 +1122,10 @@ async fn join_room_by_id_helper_local( { room_version_id }, - _ => return Err(Error::BadServerResponse("Room version is not supported")), + _ => return Err!(BadServerResponse("Room version is not supported")), }; let mut join_event_stub: CanonicalJsonObject = serde_json::from_str(make_join_response.event.get()) - .map_err(|_| Error::BadServerResponse("Invalid make_join event json received from server."))?; + .map_err(|e| err!(BadServerResponse("Invalid make_join event json received from server: {e:?}")))?; let join_authorized_via_users_server = join_event_stub .get("content") .map(|s| { @@ -1250,7 +1250,7 @@ async fn join_room_by_id_helper_local( async fn make_join_request( services: &Services, sender_user: &UserId, room_id: &RoomId, servers: &[OwnedServerName], ) -> Result<(federation::membership::prepare_join_event::v1::Response, OwnedServerName)> { - let mut make_join_response_and_server = Err(Error::BadServerResponse("No server available to assist in joining.")); + let mut make_join_response_and_server = Err!(BadServerResponse("No server available to assist in joining.")); let mut make_join_counter: u16 = 0; let mut incompatible_room_version_count: u8 = 0; @@ -1291,8 +1291,7 @@ async fn make_join_request( "15 servers have responded with M_INCOMPATIBLE_ROOM_VERSION or M_UNSUPPORTED_ROOM_VERSION, \ assuming that Conduwuit does not support the room {room_id}: {e}" ); - make_join_response_and_server = - Err(Error::BadServerResponse("Room version is not supported by Conduwuit")); + make_join_response_and_server = Err!(BadServerResponse("Room version is not supported by Conduwuit")); return make_join_response_and_server; } @@ -1300,8 +1299,7 @@ async fn make_join_request( warn!( "50 servers failed to provide valid make_join response, assuming no server can assist in joining." ); - make_join_response_and_server = - Err(Error::BadServerResponse("No server available to assist in joining.")); + make_join_response_and_server = Err!(BadServerResponse("No server available to assist in joining.")); return make_join_response_and_server; } } @@ -1321,8 +1319,8 @@ pub async fn validate_and_add_event_id( pub_key_map: &RwLock>>, ) -> Result<(OwnedEventId, CanonicalJsonObject)> { let mut value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { - error!("Invalid PDU in server response: {:?}: {:?}", pdu, e); - Error::BadServerResponse("Invalid PDU in server response") + debug_error!("Invalid PDU in server response: {pdu:#?}"); + err!(BadServerResponse("Invalid PDU in server response: {e:?}")) })?; let event_id = EventId::parse(format!( "${}", @@ -1358,15 +1356,15 @@ pub async fn validate_and_add_event_id( const MIN: u64 = 60 * 5; const MAX: u64 = 60 * 60 * 24; if continue_exponential_backoff_secs(MIN, MAX, time.elapsed(), *tries) { - debug!("Backing off from {event_id}"); - return Err(Error::BadServerResponse("bad event, still backing off")); + return Err!(BadServerResponse("bad event {event_id:?}, still backing off")); } } if let Err(e) = ruma::signatures::verify_event(&*pub_key_map.read().await, &value, room_version) { - warn!("Event {} failed verification {:?} {}", event_id, pdu, e); + debug_error!("Event {event_id} failed verification {pdu:#?}"); + let e = Err!(BadServerResponse(debug_error!("Event {event_id} failed verification: {e:?}"))); back_off(event_id).await; - return Err(Error::BadServerResponse("Event failed verification.")); + return e; } value.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.as_str().to_owned())); @@ -1648,7 +1646,7 @@ pub async fn leave_room(services: &Services, user_id: &UserId, room_id: &RoomId, } async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &RoomId) -> Result<()> { - let mut make_leave_response_and_server = Err(Error::BadServerResponse("No server available to assist in leaving.")); + let mut make_leave_response_and_server = Err!(BadServerResponse("No server available to assist in leaving.")); let invite_state = services .rooms @@ -1705,11 +1703,11 @@ async fn remote_leave_room(services: &Services, user_id: &UserId, room_id: &Room { version }, - _ => return Err(Error::BadServerResponse("Room version is not supported")), + _ => return Err!(BadServerResponse("Room version is not supported")), }; let mut leave_event_stub = serde_json::from_str::(make_leave_response.event.get()) - .map_err(|_| Error::BadServerResponse("Invalid make_leave event json received from server."))?; + .map_err(|e| err!(BadServerResponse("Invalid make_leave event json received from server: {e:?}")))?; // TODO: Is origin needed? leave_event_stub.insert( diff --git a/src/core/error/mod.rs b/src/core/error/mod.rs index 730220ac..89148d8c 100644 --- a/src/core/error/mod.rs +++ b/src/core/error/mod.rs @@ -86,13 +86,13 @@ pub enum Error { // conduwuit #[error("Arithmetic operation failed: {0}")] Arithmetic(Cow<'static, str>), + #[error("{0}")] + BadServerResponse(Cow<'static, str>), #[error("There was a problem with the '{0}' directive in your configuration: {1}")] Config(&'static str, Cow<'static, str>), #[error("{0}")] Database(Cow<'static, str>), #[error("{0}")] - BadServerResponse(&'static str), - #[error("{0}")] Conflict(&'static str), // This is only needed for when a room alias already exists // unique / untyped diff --git a/src/core/pdu/mod.rs b/src/core/pdu/mod.rs index c7c2acf5..439c831a 100644 --- a/src/core/pdu/mod.rs +++ b/src/core/pdu/mod.rs @@ -23,7 +23,7 @@ use serde_json::{ value::{to_raw_value, RawValue as RawJsonValue}, }; -use crate::{warn, Error}; +use crate::{err, warn, Error}; #[derive(Deserialize)] struct ExtractRedactedBecause { @@ -396,10 +396,8 @@ impl Ord for PduEvent { pub fn gen_event_id_canonical_json( pdu: &RawJsonValue, room_version_id: &RoomVersionId, ) -> crate::Result<(OwnedEventId, CanonicalJsonObject)> { - let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { - warn!("Error parsing incoming event {:?}: {:?}", pdu, e); - Error::BadServerResponse("Invalid PDU in server response") - })?; + let value: CanonicalJsonObject = serde_json::from_str(pdu.get()) + .map_err(|e| err!(BadServerResponse(warn!("Error parsing incoming event: {e:?}"))))?; let event_id = format!( "${}", diff --git a/src/service/media/preview.rs b/src/service/media/preview.rs index ebfd22e7..ac24d81a 100644 --- a/src/service/media/preview.rs +++ b/src/service/media/preview.rs @@ -1,10 +1,9 @@ use std::{io::Cursor, time::SystemTime}; -use conduit::{debug, utils, warn, Error, Result}; +use conduit::{debug, utils, warn, Err, Result}; use conduit_core::implement; use image::ImageReader as ImgReader; use ipaddress::IPAddress; -use ruma::api::client::error::ErrorKind; use serde::Serialize; use url::Url; use webpage::HTML; @@ -89,7 +88,7 @@ pub async fn get_url_preview(&self, url: &str) -> Result { async fn request_url_preview(&self, url: &str) -> Result { if let Ok(ip) = IPAddress::parse(url) { if !self.services.globals.valid_cidr_range(&ip) { - return Err(Error::BadServerResponse("Requesting from this address is forbidden")); + return Err!(BadServerResponse("Requesting from this address is forbidden")); } } @@ -99,7 +98,7 @@ async fn request_url_preview(&self, url: &str) -> Result { if let Some(remote_addr) = response.remote_addr() { if let Ok(ip) = IPAddress::parse(remote_addr.ip().to_string()) { if !self.services.globals.valid_cidr_range(&ip) { - return Err(Error::BadServerResponse("Requesting from this address is forbidden")); + return Err!(BadServerResponse("Requesting from this address is forbidden")); } } } @@ -109,12 +108,12 @@ async fn request_url_preview(&self, url: &str) -> Result { .get(reqwest::header::CONTENT_TYPE) .and_then(|x| x.to_str().ok()) else { - return Err(Error::BadRequest(ErrorKind::Unknown, "Unknown Content-Type")); + return Err!(Request(Unknown("Unknown Content-Type"))); }; let data = match content_type { html if html.starts_with("text/html") => self.download_html(url).await?, img if img.starts_with("image/") => self.download_image(url).await?, - _ => return Err(Error::BadRequest(ErrorKind::Unknown, "Unsupported Content-Type")), + _ => return Err!(Request(Unknown("Unsupported Content-Type"))), }; self.set_url_preview(url, &data).await?; @@ -142,7 +141,7 @@ async fn download_html(&self, url: &str) -> Result { } let body = String::from_utf8_lossy(&bytes); let Ok(html) = HTML::from_string(body.to_string(), Some(url.to_owned())) else { - return Err(Error::BadRequest(ErrorKind::Unknown, "Failed to parse HTML")); + return Err!(Request(Unknown("Failed to parse HTML"))); }; let mut data = match html.opengraph.images.first() { diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index 873f0f49..de87264c 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -3,7 +3,7 @@ mod data; use std::{fmt::Debug, mem, sync::Arc}; use bytes::BytesMut; -use conduit::{debug_info, info, trace, utils::string_from_bytes, warn, Error, PduEvent, Result}; +use conduit::{debug_error, err, trace, utils::string_from_bytes, warn, Err, PduEvent, Result}; use ipaddress::IPAddress; use ruma::{ api::{ @@ -84,8 +84,9 @@ impl Service { let http_request = request .try_into_http_request::(&dest, SendAccessToken::IfRequired(""), &VERSIONS) .map_err(|e| { - warn!("Failed to find destination {dest} for push gateway: {e}"); - Error::BadServerResponse("Invalid push gateway destination") + err!(BadServerResponse(warn!( + "Failed to find destination {dest} for push gateway: {e}" + ))) })? .map(BytesMut::freeze); @@ -95,7 +96,7 @@ impl Service { trace!("Checking request URL for IP"); if let Ok(ip) = IPAddress::parse(url_host) { if !self.services.globals.valid_cidr_range(&ip) { - return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); + return Err!(BadServerResponse("Not allowed to send requests to this IP")); } } } @@ -110,7 +111,7 @@ impl Service { if let Some(remote_addr) = response.remote_addr() { if let Ok(ip) = IPAddress::parse(remote_addr.ip().to_string()) { if !self.services.globals.valid_cidr_range(&ip) { - return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); + return Err!(BadServerResponse("Not allowed to send requests to this IP")); } } } @@ -129,10 +130,10 @@ impl Service { let body = response.bytes().await?; // TODO: handle timeout if !status.is_success() { - info!("Push gateway {dest} returned unsuccessful HTTP response ({status})"); - debug_info!("Push gateway response body: {:?}", string_from_bytes(&body)); - - return Err(Error::BadServerResponse("Push gateway returned unsuccessful response")); + debug_error!("Push gateway response body: {:?}", string_from_bytes(&body)); + return Err!(BadServerResponse(error!( + "Push gateway {dest} returned unsuccessful HTTP response: {status}" + ))); } let response = T::IncomingResponse::try_from_http_response( @@ -140,13 +141,11 @@ impl Service { .body(body) .expect("reqwest body is valid http body"), ); - response.map_err(|e| { - warn!("Push gateway {dest} returned invalid response bytes: {e}"); - Error::BadServerResponse("Push gateway returned bad/invalid response") - }) + response + .map_err(|e| err!(BadServerResponse(error!("Push gateway {dest} returned invalid response: {e}")))) }, Err(e) => { - warn!("Could not send request to pusher {dest}: {e}"); + debug_error!("Could not send request to pusher {dest}: {e}"); Err(e.into()) }, } @@ -165,7 +164,7 @@ impl Service { .room_state_get(&pdu.room_id, &StateEventType::RoomPowerLevels, "")? .map(|ev| { serde_json::from_str(ev.content.get()) - .map_err(|_| Error::bad_database("invalid m.room.power_levels event")) + .map_err(|e| err!(Database("invalid m.room.power_levels event: {e:?}"))) }) .transpose()? .unwrap_or_default(); @@ -181,8 +180,8 @@ impl Service { }; if notify.is_some() { - return Err(Error::bad_database( - r#"Malformed pushrule contains more than one of these actions: ["dont_notify", "notify", "coalesce"]"#, + return Err!(Database( + r#"Malformed pushrule contains more than one of these actions: ["dont_notify", "notify", "coalesce"]"# )); } diff --git a/src/service/resolver/actual.rs b/src/service/resolver/actual.rs index d940c514..623e3a96 100644 --- a/src/service/resolver/actual.rs +++ b/src/service/resolver/actual.rs @@ -4,7 +4,7 @@ use std::{ sync::Arc, }; -use conduit::{debug, debug_error, debug_info, debug_warn, trace, Err, Error, Result}; +use conduit::{debug, debug_error, debug_info, debug_warn, err, trace, Err, Result}; use hickory_resolver::{error::ResolveError, lookup::SrvLookup}; use ipaddress::IPAddress; use ruma::ServerName; @@ -329,10 +329,8 @@ impl super::Service { dest.is_ip_literal() || !IPAddress::is_valid(dest.host()), "Destination is not an IP literal." ); - let ip = IPAddress::parse(dest.host()).map_err(|e| { - debug_error!("Failed to parse IP literal from string: {}", e); - Error::BadServerResponse("Invalid IP address") - })?; + let ip = IPAddress::parse(dest.host()) + .map_err(|e| err!(BadServerResponse(debug_error!("Failed to parse IP literal from string: {e}"))))?; self.validate_ip(&ip)?; @@ -341,7 +339,7 @@ impl super::Service { pub(crate) fn validate_ip(&self, ip: &IPAddress) -> Result<()> { if !self.services.globals.valid_cidr_range(ip) { - return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); + return Err!(BadServerResponse("Not allowed to send requests to this IP")); } Ok(()) diff --git a/src/service/rooms/event_handler/parse_incoming_pdu.rs b/src/service/rooms/event_handler/parse_incoming_pdu.rs index a19862a5..a7ffe193 100644 --- a/src/service/rooms/event_handler/parse_incoming_pdu.rs +++ b/src/service/rooms/event_handler/parse_incoming_pdu.rs @@ -1,18 +1,18 @@ -use conduit::{pdu::gen_event_id_canonical_json, warn, Err, Error, Result}; -use ruma::{api::client::error::ErrorKind, CanonicalJsonObject, OwnedEventId, OwnedRoomId, RoomId}; +use conduit::{debug_warn, err, pdu::gen_event_id_canonical_json, Err, Result}; +use ruma::{CanonicalJsonObject, OwnedEventId, OwnedRoomId, RoomId}; use serde_json::value::RawValue as RawJsonValue; impl super::Service { pub fn parse_incoming_pdu(&self, pdu: &RawJsonValue) -> Result<(OwnedEventId, CanonicalJsonObject, OwnedRoomId)> { let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { - warn!("Error parsing incoming event {pdu:?}: {e:?}"); - Error::BadServerResponse("Invalid PDU in server response") + debug_warn!("Error parsing incoming event {pdu:#?}"); + err!(BadServerResponse("Error parsing incoming event {e:?}")) })?; let room_id: OwnedRoomId = value .get("room_id") .and_then(|id| RoomId::parse(id.as_str()?).ok()) - .ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Invalid room id in pdu"))?; + .ok_or(err!(Request(InvalidParam("Invalid room id in pdu"))))?; let Ok(room_version_id) = self.services.state.get_room_version(&room_id) else { return Err!("Server is not in room {room_id}"); diff --git a/src/service/sending/appservice.rs b/src/service/sending/appservice.rs index 5ed40ad9..32dbba4a 100644 --- a/src/service/sending/appservice.rs +++ b/src/service/sending/appservice.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, mem}; use bytes::BytesMut; -use conduit::{debug_error, trace, utils, warn, Error, Result}; +use conduit::{debug_error, err, trace, utils, warn, Err, Result}; use reqwest::Client; use ruma::api::{appservice::Registration, IncomingResponse, MatrixVersion, OutgoingRequest, SendAccessToken}; @@ -26,10 +26,7 @@ where let hs_token = registration.hs_token.as_str(); let mut http_request = request .try_into_http_request::(&dest, SendAccessToken::IfRequired(hs_token), &VERSIONS) - .map_err(|e| { - warn!("Failed to find destination {dest}: {e}"); - Error::BadServerResponse("Invalid appservice destination") - })? + .map_err(|e| err!(BadServerResponse(warn!("Failed to find destination {dest}: {e}"))))? .map(BytesMut::freeze); let mut parts = http_request.uri().clone().into_parts(); @@ -69,13 +66,11 @@ where let body = response.bytes().await?; // TODO: handle timeout if !status.is_success() { - warn!( + debug_error!("Appservice response bytes: {:?}", utils::string_from_bytes(&body)); + return Err!(BadServerResponse(error!( "Appservice \"{}\" returned unsuccessful HTTP response {status} at {dest}", registration.id - ); - debug_error!("Appservice response bytes: {:?}", utils::string_from_bytes(&body)); - - return Err(Error::BadServerResponse("Appservice returned unsuccessful HTTP response")); + ))); } let response = T::IncomingResponse::try_from_http_response( @@ -85,7 +80,9 @@ where ); response.map(Some).map_err(|e| { - warn!("Appservice \"{}\" returned invalid response bytes {dest}: {e}", registration.id); - Error::BadServerResponse("Appservice returned bad/invalid response") + err!(BadServerResponse(error!( + "Appservice \"{}\" returned invalid response bytes {dest}: {e}", + registration.id + ))) }) } diff --git a/src/service/sending/send.rs b/src/service/sending/send.rs index b3a84d62..8fd467f6 100644 --- a/src/service/sending/send.rs +++ b/src/service/sending/send.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, mem}; use conduit::{ - debug, debug_error, debug_warn, error::inspect_debug_log, trace, utils::string::EMPTY, Err, Error, Result, + debug, debug_error, debug_warn, err, error::inspect_debug_log, trace, utils::string::EMPTY, Err, Error, Result, }; use http::{header::AUTHORIZATION, HeaderValue}; use ipaddress::IPAddress; @@ -62,7 +62,7 @@ impl super::Service { trace!("Preparing request"); let mut http_request = req .try_into_http_request::>(&actual.string, SATIR, &VERSIONS) - .map_err(|_| Error::BadServerResponse("Invalid destination"))?; + .map_err(|e| err!(BadServerResponse("Invalid destination: {e:?}")))?; sign_request::(&self.services.globals, dest, &mut http_request); @@ -139,10 +139,7 @@ where ); } - match response { - Err(_) => Err(Error::BadServerResponse("Server returned bad 200 response.")), - Ok(response) => Ok(response), - } + response.map_err(|e| err!(BadServerResponse("Server returned bad 200 response: {e:?}"))) } fn handle_error( diff --git a/src/service/server_keys/mod.rs b/src/service/server_keys/mod.rs index b27279af..a565e500 100644 --- a/src/service/server_keys/mod.rs +++ b/src/service/server_keys/mod.rs @@ -4,7 +4,7 @@ use std::{ time::{Duration, SystemTime}, }; -use conduit::{debug, error, info, trace, warn, Error, Result}; +use conduit::{debug, debug_error, debug_warn, err, error, info, trace, warn, Err, Result}; use futures_util::{stream::FuturesUnordered, StreamExt}; use ruma::{ api::federation::{ @@ -57,13 +57,13 @@ impl Service { for event in events { for (signature_server, signature) in event .get("signatures") - .ok_or(Error::BadServerResponse("No signatures in server response pdu."))? + .ok_or(err!(BadServerResponse("No signatures in server response pdu.")))? .as_object() - .ok_or(Error::BadServerResponse("Invalid signatures object in server response pdu."))? + .ok_or(err!(BadServerResponse("Invalid signatures object in server response pdu.")))? { - let signature_object = signature.as_object().ok_or(Error::BadServerResponse( + let signature_object = signature.as_object().ok_or(err!(BadServerResponse( "Invalid signatures content object in server response pdu.", - ))?; + )))?; for signature_id in signature_object.keys() { server_key_ids @@ -94,10 +94,12 @@ impl Service { .map(|(signature_server, signature_ids)| async { let fetch_res = self .fetch_signing_keys_for_server( - signature_server.as_str().try_into().map_err(|_| { + signature_server.as_str().try_into().map_err(|e| { ( signature_server.clone(), - Error::BadServerResponse("Invalid servername in signatures of server response pdu."), + err!(BadServerResponse( + "Invalid servername in signatures of server response pdu: {e:?}" + )), ) })?, signature_ids.into_iter().collect(), // HashSet to Vec @@ -107,7 +109,9 @@ impl Service { match fetch_res { Ok(keys) => Ok((signature_server, keys)), Err(e) => { - warn!("Signature verification failed: Could not fetch signing key for {signature_server}: {e}",); + debug_error!( + "Signature verification failed: Could not fetch signing key for {signature_server}: {e}", + ); Err((signature_server, e)) }, } @@ -123,7 +127,7 @@ impl Service { .insert(signature_server.clone(), keys); }, Err((signature_server, e)) => { - warn!("Failed to fetch keys for {}: {:?}", signature_server, e); + debug_warn!("Failed to fetch keys for {signature_server}: {e:?}"); }, } } @@ -141,35 +145,37 @@ impl Service { pub_key_map: &mut RwLockWriteGuard<'_, BTreeMap>>, ) -> Result<()> { let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { - error!("Invalid PDU in server response: {:?}: {:?}", pdu, e); - Error::BadServerResponse("Invalid PDU in server response") + debug_error!("Invalid PDU in server response: {pdu:#?}"); + err!(BadServerResponse(error!("Invalid PDU in server response: {e:?}"))) })?; let signatures = value .get("signatures") - .ok_or(Error::BadServerResponse("No signatures in server response pdu."))? + .ok_or(err!(BadServerResponse("No signatures in server response pdu.")))? .as_object() - .ok_or(Error::BadServerResponse("Invalid signatures object in server response pdu."))?; + .ok_or(err!(BadServerResponse("Invalid signatures object in server response pdu.")))?; for (signature_server, signature) in signatures { - let signature_object = signature.as_object().ok_or(Error::BadServerResponse( + let signature_object = signature.as_object().ok_or(err!(BadServerResponse( "Invalid signatures content object in server response pdu.", - ))?; + )))?; let signature_ids = signature_object.keys().cloned().collect::>(); let contains_all_ids = |keys: &BTreeMap| signature_ids.iter().all(|id| keys.contains_key(id)); - let origin = <&ServerName>::try_from(signature_server.as_str()) - .map_err(|_| Error::BadServerResponse("Invalid servername in signatures of server response pdu."))?; + let origin = <&ServerName>::try_from(signature_server.as_str()).map_err(|e| { + err!(BadServerResponse( + "Invalid servername in signatures of server response pdu: {e:?}" + )) + })?; if servers.contains_key(origin) || pub_key_map.contains_key(origin.as_str()) { continue; } - debug!("Loading signing keys for {}", origin); - + debug!("Loading signing keys for {origin}"); let result: BTreeMap<_, _> = self .services .globals @@ -179,7 +185,7 @@ impl Service { .collect(); if !contains_all_ids(&result) { - debug!("Signing key not loaded for {}", origin); + debug_warn!("Signing key not loaded for {origin}"); servers.insert(origin.to_owned(), BTreeMap::new()); } @@ -196,7 +202,7 @@ impl Service { pub_key_map: &RwLock>>, ) -> Result<()> { for server in self.services.globals.trusted_servers() { - debug!("Asking batch signing keys from trusted server {}", server); + debug!("Asking batch signing keys from trusted server {server}"); match self .services .sending @@ -209,14 +215,16 @@ impl Service { .await { Ok(keys) => { - debug!("Got signing keys: {:?}", keys); + debug!("Got signing keys: {keys:?}"); let mut pkm = pub_key_map.write().await; for k in keys.server_keys { let k = match k.deserialize() { Ok(key) => key, Err(e) => { - warn!("Received error {e} while fetching keys from trusted server {server}"); - warn!("{}", k.into_json()); + warn!( + "Received error {e} while fetching keys from trusted server {server}: {:#?}", + k.into_json() + ); continue; }, }; @@ -236,13 +244,10 @@ impl Service { pkm.insert(k.server_name.to_string(), result); } }, - Err(e) => { - warn!( - "Failed sending batched key request to trusted key server {server} for the remote servers \ - {:?}: {e}", - servers - ); - }, + Err(e) => error!( + "Failed sending batched key request to trusted key server {server} for the remote servers \ + {servers:?}: {e}" + ), } } @@ -478,7 +483,6 @@ impl Service { } } else { info!("query_trusted_key_servers_first is set to false, querying {origin} first"); - debug!("Asking {origin} for their signing keys over federation"); if let Some(server_key) = self .services @@ -536,7 +540,7 @@ impl Service { .filter_map(|e| e.deserialize().ok()) .collect::>() }) { - debug!("Got signing keys: {:?}", server_keys); + debug!("Got signing keys: {server_keys:?}"); for k in server_keys { self.services .globals @@ -561,7 +565,6 @@ impl Service { } } - warn!("Failed to find public key for server: {origin}"); - Err(Error::BadServerResponse("Failed to find public key for server")) + Err!(BadServerResponse(warn!("Failed to find public key for server {origin:?}"))) } }