diff --git a/src/uucore/src/lib/mods/error.rs b/src/uucore/src/lib/mods/error.rs index 6149f527667..5897f658532 100644 --- a/src/uucore/src/lib/mods/error.rs +++ b/src/uucore/src/lib/mods/error.rs @@ -479,9 +479,15 @@ impl Display for UIoError { /// ``` pub fn strip_errno(err: &std::io::Error) -> String { let mut msg = err.to_string(); - if let Some(pos) = msg.find(" (os error ") { - msg.truncate(pos); + + if let Some((prefix, suffix)) = msg.rsplit_once(" (os error ") + && suffix + .strip_suffix(')') + .is_some_and(|n| n.parse::().is_ok()) + { + msg.truncate(prefix.len()); } + msg } @@ -797,6 +803,28 @@ impl Display for ClapErrorWrapper { #[cfg(test)] mod tests { + #[test] + fn test_strip_errno_removes_trailing_os_error() { + use super::strip_errno; + use std::io::Error; + + let err = Error::from_raw_os_error(2); + assert_eq!(strip_errno(&err), "No such file or directory"); + } + + #[test] + fn strip_errno_preserves_nontrailing_os_error() { + use super::strip_errno; + use std::io::Error; + + let err = Error::other(r#"Permission denied (os error 13) at path "/tmp.haKXBI6xNU""#); + + assert_eq!( + strip_errno(&err), + r#"Permission denied (os error 13) at path "/tmp.haKXBI6xNU""# + ); + } + #[test] #[cfg(unix)] fn test_nix_error_conversion() {