For failures and malformed inputs, implement error handling that (1) degrades gracefully instead of panicking, (2) preserves correctness across partial/streamed boundaries, and (3) reports errors safely with strict bounds.
Guidelines
Example pattern: stateful UTF-8 boundary handling
fn split_utf8(bytes: Vec<u8>) -> (String, Vec<u8>) {
match std::str::from_utf8(&bytes) {
Ok(text) => (text.to_string(), Vec::new()),
Err(err) => {
// Carry over only the genuinely incomplete suffix; never drop/garble valid prefix.
let valid = err.valid_up_to();
let carry_len = bytes.len() - valid;
if err.error_len().is_none() && carry_len < 4 {
(String::from_utf8_lossy(&bytes[..valid]).into_owned(), bytes[valid..].to_vec())
} else {
(String::from_utf8_lossy(&bytes).into_owned(), Vec::new())
}
}
}
}
Apply this standard whenever you: