From 54403cf2b6d8df367aa511ba113c70ed3f4ed18d Mon Sep 17 00:00:00 2001 From: Hussenet Thomas <113238884+LeJamon@users.noreply.github.com> Date: Sat, 30 May 2026 15:38:25 +0200 Subject: [PATCH] fix(#166): preserve Utf8Error detail in hex_to_str XRPLUtilsException::Utf8Error was a unit variant and its From impl discarded the underlying core::str::Utf8Error, hiding the position and valid-up-to information. Carry the Utf8Error so callers can diagnose which byte was invalid. --- src/utils/exceptions.rs | 10 ++-------- src/utils/str_conversion.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/utils/exceptions.rs b/src/utils/exceptions.rs index 7efc3031..9b19d4e6 100644 --- a/src/utils/exceptions.rs +++ b/src/utils/exceptions.rs @@ -39,8 +39,8 @@ pub enum XRPLUtilsException { FromHexError(#[from] hex::FromHexError), #[error("ParseInt error: {0}")] ParseIntError(#[from] core::num::ParseIntError), - #[error("Invalid UTF-8")] - Utf8Error, + #[error("Invalid UTF-8: {0}")] + Utf8Error(#[from] core::str::Utf8Error), } #[derive(Debug, Clone, PartialEq, Error)] @@ -119,12 +119,6 @@ pub enum ISOCodeException { UnsupportedCurrencyRepresentation, } -impl From for XRPLUtilsException { - fn from(_: core::str::Utf8Error) -> Self { - XRPLUtilsException::Utf8Error - } -} - impl From for XRPLUtilsException { fn from(error: serde_json::Error) -> Self { XRPLUtilsException::SerdeJsonError(error.into()) diff --git a/src/utils/str_conversion.rs b/src/utils/str_conversion.rs index 42dd6333..84acfabb 100644 --- a/src/utils/str_conversion.rs +++ b/src/utils/str_conversion.rs @@ -63,4 +63,16 @@ mod tests { let result = hex_to_str(Cow::Borrowed("ff")); assert!(result.is_err()); } + + #[test] + fn test_hex_to_str_invalid_utf8_preserves_detail() { + use crate::utils::exceptions::XRPLUtilsException; + + // "41ff" decodes to [0x41, 0xff]: 'A' is valid, 0xff is not, so the + // Utf8Error should report `valid_up_to() == 1`. + match hex_to_str(Cow::Borrowed("41ff")).unwrap_err() { + XRPLUtilsException::Utf8Error(error) => assert_eq!(error.valid_up_to(), 1), + other => panic!("expected Utf8Error, got {other:?}"), + } + } }