diff --git a/src/api/client/sync.rs b/src/api/client/sync.rs index 5940d7cf..f0b26e80 100644 --- a/src/api/client/sync.rs +++ b/src/api/client/sync.rs @@ -6,10 +6,8 @@ use std::{ use axum::extract::State; use conduit::{ - debug, err, error, - error::is_not_found, - is_equal_to, - result::IntoIsOk, + debug, err, error, is_equal_to, + result::{FlatOk, IntoIsOk}, utils::{ math::{ruma_from_u64, ruma_from_usize, usize_from_ruma, usize_from_u64_truncated}, BoolExt, IterStream, ReadyExt, TryFutureExtExt, @@ -1891,7 +1889,7 @@ async fn filter_rooms( .filter_map(|r| async move { let room_type = services.rooms.state_accessor.get_room_type(r).await; - if room_type.as_ref().is_err_and(|e| !is_not_found(e)) { + if room_type.as_ref().is_err_and(|e| !e.is_not_found()) { return None; } diff --git a/src/api/server/send.rs b/src/api/server/send.rs index bb424988..50a79e00 100644 --- a/src/api/server/send.rs +++ b/src/api/server/send.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeMap, net::IpAddr, time::Instant}; use axum::extract::State; use axum_client_ip::InsecureClientIp; -use conduit::{debug, debug_warn, err, result::LogErr, trace, utils::ReadyExt, warn, Err, Error, Result}; +use conduit::{debug, debug_warn, err, error, result::LogErr, trace, utils::ReadyExt, warn, Err, Error, Result}; use futures::StreamExt; use ruma::{ api::{ @@ -85,7 +85,7 @@ pub(crate) async fn send_transaction_message_route( Ok(send_transaction_message::v1::Response { pdus: resolved_map .into_iter() - .map(|(e, r)| (e, r.map_err(|e| e.sanitized_string()))) + .map(|(e, r)| (e, r.map_err(error::sanitized_message))) .collect(), }) } diff --git a/src/core/error/mod.rs b/src/core/error/mod.rs index ad7f9f3c..39fa4340 100644 --- a/src/core/error/mod.rs +++ b/src/core/error/mod.rs @@ -120,17 +120,19 @@ pub enum Error { } impl Error { + //#[deprecated] pub fn bad_database(message: &'static str) -> Self { crate::err!(Database(error!("{message}"))) } /// Sanitizes public-facing errors that can leak sensitive information. - pub fn sanitized_string(&self) -> String { + pub fn sanitized_message(&self) -> String { match self { Self::Database(..) => String::from("Database error occurred."), Self::Io(..) => String::from("I/O error occurred."), - _ => self.to_string(), + _ => self.message(), } } + /// Generate the error message string. pub fn message(&self) -> String { match self { Self::Federation(ref origin, ref error) => format!("Answer from {origin}: {error}"), @@ -151,6 +153,8 @@ impl Error { } } + /// Returns the HTTP error code or closest approximation based on error + /// variant. pub fn status_code(&self) -> http::StatusCode { use http::StatusCode; @@ -163,10 +167,17 @@ impl Error { _ => StatusCode::INTERNAL_SERVER_ERROR, } } + + /// Returns true for "not found" errors. This means anything that qualifies + /// as a "not found" from any variant's contained error type. This call is + /// often used as a special case to eliminate a contained Option with a + /// Result where Ok(None) is instead Err(e) if e.is_not_found(). + #[inline] + pub fn is_not_found(&self) -> bool { self.status_code() == http::StatusCode::NOT_FOUND } } impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{self}") } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.message()) } } #[allow(clippy::fallible_impl_from)] @@ -184,6 +195,8 @@ pub fn infallible(_e: &Infallible) { panic!("infallible error should never exist"); } +/// Convenience functor for fundamental Error::sanitized_message(); see member. #[inline] #[must_use] -pub fn is_not_found(e: &Error) -> bool { e.status_code() == http::StatusCode::NOT_FOUND } +#[allow(clippy::needless_pass_by_value)] +pub fn sanitized_message(e: Error) -> String { e.sanitized_message() } diff --git a/src/core/result/not_found.rs b/src/core/result/not_found.rs index 69ce821b..d61825af 100644 --- a/src/core/result/not_found.rs +++ b/src/core/result/not_found.rs @@ -1,5 +1,5 @@ use super::Result; -use crate::{error, Error}; +use crate::Error; pub trait NotFound { #[must_use] @@ -8,5 +8,5 @@ pub trait NotFound { impl NotFound for Result { #[inline] - fn is_not_found(&self) -> bool { self.as_ref().is_err_and(error::is_not_found) } + fn is_not_found(&self) -> bool { self.as_ref().is_err_and(Error::is_not_found) } }