diff --git a/ruma-api-macros/src/api.rs b/ruma-api-macros/src/api.rs index 348093ce..d7741437 100644 --- a/ruma-api-macros/src/api.rs +++ b/ruma-api-macros/src/api.rs @@ -151,9 +151,16 @@ impl ToTokens for Api { use ruma_api::error::RequestDeserializationError; let segment = path_segments.get(#i).unwrap().as_bytes(); - let decoded = - ruma_api::exports::percent_encoding::percent_decode(segment) - .decode_utf8_lossy(); + let decoded = match ruma_api::exports::percent_encoding::percent_decode( + segment + ).decode_utf8() { + Ok(x) => x, + Err(err) => { + return Err( + RequestDeserializationError::new(err, request).into() + ); + } + }; match std::convert::TryFrom::try_from(decoded.deref()) { Ok(val) => val, Err(err) => { diff --git a/src/error.rs b/src/error.rs index 1047c58a..b3d17c9d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -191,6 +191,7 @@ enum SerializationError { #[doc(hidden)] #[derive(Debug)] pub enum DeserializationError { + Utf8(std::str::Utf8Error), Json(serde_json::Error), Query(serde_urlencoded::de::Error), Ident(ruma_identifiers::Error), @@ -202,6 +203,7 @@ pub enum DeserializationError { impl Display for DeserializationError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { + DeserializationError::Utf8(err) => Display::fmt(err, f), DeserializationError::Json(err) => Display::fmt(err, f), DeserializationError::Query(err) => Display::fmt(err, f), DeserializationError::Ident(err) => Display::fmt(err, f), @@ -210,6 +212,13 @@ impl Display for DeserializationError { } } +#[doc(hidden)] +impl From for DeserializationError { + fn from(err: std::str::Utf8Error) -> Self { + Self::Utf8(err) + } +} + #[doc(hidden)] impl From for DeserializationError { fn from(err: serde_json::Error) -> Self { diff --git a/src/lib.rs b/src/lib.rs index 2dfcb7f0..fd9abb37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -352,7 +352,13 @@ mod tests { room_id: request_body.room_id, room_alias: { let segment = path_segments.get(5).unwrap().as_bytes(); - let decoded = percent_encoding::percent_decode(segment).decode_utf8_lossy(); + let decoded = match percent_encoding::percent_decode(segment).decode_utf8() + { + Ok(x) => x, + Err(err) => { + return Err(RequestDeserializationError::new(err, request).into()) + } + }; match serde_json::from_str(decoded.deref()) { Ok(id) => id, Err(err) => {