bin_ser: preserve IO errors on deserialization

We're starting to deserialize directly from the TcpStream now, which
means that a socket error gets logged as "deserialize error". That's not
very helpful; preserve the io::Error so it can be logged.
This commit is contained in:
Eric Seppanen
2021-05-13 16:07:41 -07:00
committed by Eric Seppanen
parent 3296b7d770
commit d744ddee7c

View File

@@ -15,7 +15,7 @@
use bincode::Options;
use serde::{de::DeserializeOwned, Serialize};
use std::io::{Read, Write};
use std::io::{self, Read, Write};
use thiserror::Error;
/// An error that occurred during a deserialize operation
@@ -23,8 +23,23 @@ use thiserror::Error;
/// This could happen because the input data was too short,
/// or because an invalid value was encountered.
#[derive(Debug, Error)]
#[error("deserialize error")]
pub struct DeserializeError;
pub enum DeserializeError {
/// The deserializer isn't able to deserialize the supplied data.
#[error("deserialize error")]
BadInput,
/// While deserializing from a `Read` source, an `io::Error` occurred.
#[error("deserialize error: {0}")]
Io(io::Error),
}
impl From<bincode::Error> for DeserializeError {
fn from(e: bincode::Error) -> Self {
match *e {
bincode::ErrorKind::Io(io_err) => DeserializeError::Io(io_err),
_ => DeserializeError::BadInput,
}
}
}
/// An error that occurred during a serialize operation
///
@@ -89,12 +104,14 @@ pub trait BeSer: Serialize + DeserializeOwned {
/// Deserialize from a byte slice
fn des(buf: &[u8]) -> Result<Self, DeserializeError> {
be_coder().deserialize(buf).or(Err(DeserializeError))
be_coder()
.deserialize(buf)
.or(Err(DeserializeError::BadInput))
}
/// Deserialize from a reader
fn des_from<R: Read>(r: &mut R) -> Result<Self, DeserializeError> {
be_coder().deserialize_from(r).or(Err(DeserializeError))
be_coder().deserialize_from(r).map_err(|e| e.into())
}
}
@@ -121,61 +138,16 @@ pub trait LeSer: Serialize + DeserializeOwned {
le_coder().serialize(&self).or(Err(SerializeError))
}
/// Deserialize from a byte slice
fn des(buf: &[u8]) -> Result<Self, DeserializeError> {
le_coder().deserialize(buf).or(Err(DeserializeError))
}
/// Deserialize from a reader
fn des_from<R: Read>(r: &mut R) -> Result<Self, DeserializeError> {
le_coder().deserialize_from(r).or(Err(DeserializeError))
}
}
/// Binary serialize/deserialize helper functions (Big Endian)
///
/// This version panics on every serialization/deserialization error.
/// That can be useful if you want to see a backtrace to find where the
/// error occurred.
pub trait LeSerPanic: Serialize + DeserializeOwned {
/// Serialize into a byte slice
fn ser_into_slice<W: Write>(&self, b: &mut [u8]) -> Result<(), SerializeError> {
// This is slightly awkward; we need a mutable reference to a mutable reference.
let mut w = b;
self.ser_into(&mut w)
}
/// Serialize into a borrowed writer
///
/// This is useful for most `Write` types except `&mut [u8]`, which
/// can more easily use [`ser_into_slice`](Self::ser_into_slice).
fn ser_into<W: Write>(&self, w: &mut W) -> Result<(), SerializeError> {
le_coder()
.serialize_into(w, &self)
.or_else(|e| panic!("ser_into failed: {}", e))
}
/// Serialize into a new heap-allocated buffer
fn ser(&self) -> Result<Vec<u8>, SerializeError> {
le_coder()
.serialize(&self)
.or_else(|e| panic!("ser failed: {}", e))
}
/// Deserialize from a byte slice
fn des(buf: &[u8]) -> Result<Self, DeserializeError> {
le_coder()
.deserialize(buf)
.or_else(|e| panic!("des failed: {}", e))
.or(Err(DeserializeError::BadInput))
}
/// Deserialize from a reader
///
/// tip: `&[u8]` implements `Read`
fn des_from<R: Read>(r: &mut R) -> Result<Self, DeserializeError> {
le_coder()
.deserialize_from(r)
.or_else(|e| panic!("des_from failed: {}", e))
le_coder().deserialize_from(r).map_err(|e| e.into())
}
}
@@ -183,10 +155,9 @@ impl<T> BeSer for T where T: Serialize + DeserializeOwned {}
impl<T> LeSer for T where T: Serialize + DeserializeOwned {}
impl<T> LeSerPanic for T where T: Serialize + DeserializeOwned {}
#[cfg(test)]
mod tests {
use super::DeserializeError;
use serde::{Deserialize, Serialize};
use std::io::Cursor;
@@ -256,7 +227,8 @@ mod tests {
// deserialize from a `Write` sink that terminates early.
let mut buf = Cursor::new([0u8; 4]);
ShortStruct::des_from(&mut buf).unwrap_err();
let err = ShortStruct::des_from(&mut buf).unwrap_err();
assert!(matches!(err, DeserializeError::Io(_)));
}
#[test]
@@ -285,7 +257,8 @@ mod tests {
// deserialize from a `Write` sink that terminates early.
let mut buf = Cursor::new([0u8; 4]);
ShortStruct::des_from(&mut buf).unwrap_err();
let err = ShortStruct::des_from(&mut buf).unwrap_err();
assert!(matches!(err, DeserializeError::Io(_)));
}
#[test]