From 65ddb3b898966d2e66d25f5cd88e70195654300e Mon Sep 17 00:00:00 2001 From: ice_iix Date: Tue, 30 Apr 2019 19:20:32 -0700 Subject: [PATCH] Improve error reporting of invalid UTF-8 when deserializing strings std::io::Read read_to_string() [1] reports this uninformative error: thread 'main' panicked at 'Err: IOError(Custom { kind: InvalidData, error: StringError("stream did not contain valid UTF-8") })', src/server/mod.rs:442:33 Instead of read_to_string(), use read_to_end() to read into a buffer, then convert using String::from_utf8() and unwrap it. This gives a better error message when UTF-8 fails to decode: thread '' panicked at 'called Result::unwrap() on an Err value: FromUtf8Error { bytes: [105, 110, 101, 99, 114, 97, 102, 116, 58, 99, 114, 97, 102, 116, 105, 110, 103, 95, 115, 104, 97, 112, 101, 100, 20, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 98, 111, 110, 101, 95, 98, 108, 111, 99, 107, 3, 3, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 1, 134, 5, 1, 0, 1, 249, 2, 1, 0, 25, 109], error: Utf8Error { valid_up_to: 50, error_len: Some(1) } }', src/libcore/result.rs:1009:5 which is helpful for tracking down protocol errors, such as updating to a new protocol (developed for GH-132 / GH-72). [1] https://doc.rust-lang.org/nightly/std/io/trait.Read.html#method.read_to_string [2] https://doc.rust-lang.org/std/string/struct.String.html#method.from_utf8 --- protocol/src/protocol/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/protocol/src/protocol/mod.rs b/protocol/src/protocol/mod.rs index 71f52ce..bb91423 100644 --- a/protocol/src/protocol/mod.rs +++ b/protocol/src/protocol/mod.rs @@ -257,8 +257,9 @@ impl Serializable for String { let len = VarInt::read_from(buf)?.0; debug_assert!(len >= 0, "Negative string length: {}", len); debug_assert!(len <= 65536, "String length too big: {}", len); - let mut ret = String::new(); - buf.take(len as u64).read_to_string(&mut ret)?; + let mut bytes = Vec::::new(); + buf.take(len as u64).read_to_end(&mut bytes)?; + let ret = String::from_utf8(bytes).unwrap(); Result::Ok(ret) } fn write_to(&self, buf: &mut W) -> Result<(), Error> {