add is_not_found as Error member function; tweak interface; add doc comments

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-10-04 17:07:31 +00:00 committed by strawberry
parent dd9f53080a
commit 685eadb171
4 changed files with 24 additions and 13 deletions

View file

@ -6,10 +6,8 @@ use std::{
use axum::extract::State; use axum::extract::State;
use conduit::{ use conduit::{
debug, err, error, debug, err, error, is_equal_to,
error::is_not_found, result::{FlatOk, IntoIsOk},
is_equal_to,
result::IntoIsOk,
utils::{ utils::{
math::{ruma_from_u64, ruma_from_usize, usize_from_ruma, usize_from_u64_truncated}, math::{ruma_from_u64, ruma_from_usize, usize_from_ruma, usize_from_u64_truncated},
BoolExt, IterStream, ReadyExt, TryFutureExtExt, BoolExt, IterStream, ReadyExt, TryFutureExtExt,
@ -1891,7 +1889,7 @@ async fn filter_rooms(
.filter_map(|r| async move { .filter_map(|r| async move {
let room_type = services.rooms.state_accessor.get_room_type(r).await; 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; return None;
} }

View file

@ -2,7 +2,7 @@ use std::{collections::BTreeMap, net::IpAddr, time::Instant};
use axum::extract::State; use axum::extract::State;
use axum_client_ip::InsecureClientIp; 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 futures::StreamExt;
use ruma::{ use ruma::{
api::{ api::{
@ -85,7 +85,7 @@ pub(crate) async fn send_transaction_message_route(
Ok(send_transaction_message::v1::Response { Ok(send_transaction_message::v1::Response {
pdus: resolved_map pdus: resolved_map
.into_iter() .into_iter()
.map(|(e, r)| (e, r.map_err(|e| e.sanitized_string()))) .map(|(e, r)| (e, r.map_err(error::sanitized_message)))
.collect(), .collect(),
}) })
} }

View file

@ -120,17 +120,19 @@ pub enum Error {
} }
impl Error { impl Error {
//#[deprecated]
pub fn bad_database(message: &'static str) -> Self { crate::err!(Database(error!("{message}"))) } pub fn bad_database(message: &'static str) -> Self { crate::err!(Database(error!("{message}"))) }
/// Sanitizes public-facing errors that can leak sensitive information. /// Sanitizes public-facing errors that can leak sensitive information.
pub fn sanitized_string(&self) -> String { pub fn sanitized_message(&self) -> String {
match self { match self {
Self::Database(..) => String::from("Database error occurred."), Self::Database(..) => String::from("Database error occurred."),
Self::Io(..) => String::from("I/O 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 { pub fn message(&self) -> String {
match self { match self {
Self::Federation(ref origin, ref error) => format!("Answer from {origin}: {error}"), 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 { pub fn status_code(&self) -> http::StatusCode {
use http::StatusCode; use http::StatusCode;
@ -163,10 +167,17 @@ impl Error {
_ => StatusCode::INTERNAL_SERVER_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 { 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)] #[allow(clippy::fallible_impl_from)]
@ -184,6 +195,8 @@ pub fn infallible(_e: &Infallible) {
panic!("infallible error should never exist"); panic!("infallible error should never exist");
} }
/// Convenience functor for fundamental Error::sanitized_message(); see member.
#[inline] #[inline]
#[must_use] #[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() }

View file

@ -1,5 +1,5 @@
use super::Result; use super::Result;
use crate::{error, Error}; use crate::Error;
pub trait NotFound<T> { pub trait NotFound<T> {
#[must_use] #[must_use]
@ -8,5 +8,5 @@ pub trait NotFound<T> {
impl<T> NotFound<T> for Result<T, Error> { impl<T> NotFound<T> for Result<T, Error> {
#[inline] #[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) }
} }