Add encode::Error::MissingData variant
The `io::Error` is troublesome because it contains a bunch of stuff that never happens when reading from a buffer. However the EOF variant can occur if the buffer is too short. As an initial step towards reducing usage of the `io::Error` add a `MissingData` variant to the `encode::Error` and when converting from an IO error map to `MissingData` if EOF is encountered.
This commit is contained in:
parent
5a42ef2850
commit
b04142c745
|
@ -1027,13 +1027,11 @@ mod tests {
|
|||
])
|
||||
.is_err());
|
||||
|
||||
let rand_io_err = Error::Io(io::Error::new(io::ErrorKind::Other, ""));
|
||||
|
||||
// Check serialization that `if len > MAX_VEC_SIZE {return err}` isn't inclusive,
|
||||
// by making sure it fails with IO Error and not an `OversizedVectorAllocation` Error.
|
||||
// by making sure it fails with `MissingData` and not an `OversizedVectorAllocation` Error.
|
||||
let err =
|
||||
deserialize::<CheckedData>(&serialize(&(super::MAX_VEC_SIZE as u32))).unwrap_err();
|
||||
assert_eq!(discriminant(&err), discriminant(&rand_io_err));
|
||||
assert!(matches!(err, Error::MissingData));
|
||||
|
||||
test_len_is_max_vec::<u8>();
|
||||
test_len_is_max_vec::<BlockHash>();
|
||||
|
@ -1055,11 +1053,10 @@ mod tests {
|
|||
Vec<T>: Decodable,
|
||||
T: fmt::Debug,
|
||||
{
|
||||
let rand_io_err = Error::Io(io::Error::new(io::ErrorKind::Other, ""));
|
||||
let mut buf = Vec::new();
|
||||
buf.emit_compact_size(super::MAX_VEC_SIZE / mem::size_of::<T>()).unwrap();
|
||||
let err = deserialize::<Vec<T>>(&buf).unwrap_err();
|
||||
assert_eq!(discriminant(&err), discriminant(&rand_io_err));
|
||||
assert!(matches!(err, Error::MissingData));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -56,6 +56,8 @@ impl<E: fmt::Debug + std::error::Error + 'static> std::error::Error for DecodeEr
|
|||
pub enum Error {
|
||||
/// And I/O error.
|
||||
Io(io::Error),
|
||||
/// Missing data (early end of file or slice too short).
|
||||
MissingData, // TODO: Can we add more context?
|
||||
/// Tried to allocate an oversized vector.
|
||||
OversizedVectorAllocation {
|
||||
/// The capacity requested.
|
||||
|
@ -86,6 +88,7 @@ impl fmt::Display for Error {
|
|||
|
||||
match *self {
|
||||
Io(ref e) => write_err!(f, "IO error"; e),
|
||||
MissingData => write!(f, "missing data (early end of file or slice too short)"),
|
||||
OversizedVectorAllocation { requested: ref r, max: ref m } =>
|
||||
write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m),
|
||||
InvalidChecksum { expected: ref e, actual: ref a } =>
|
||||
|
@ -105,7 +108,8 @@ impl std::error::Error for Error {
|
|||
|
||||
match self {
|
||||
Io(e) => Some(e),
|
||||
OversizedVectorAllocation { .. }
|
||||
MissingData
|
||||
| OversizedVectorAllocation { .. }
|
||||
| InvalidChecksum { .. }
|
||||
| NonMinimalVarInt
|
||||
| ParseFailed(_)
|
||||
|
@ -115,7 +119,14 @@ impl std::error::Error for Error {
|
|||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(error: io::Error) -> Self { Error::Io(error) }
|
||||
fn from(e: io::Error) -> Self {
|
||||
use io::ErrorKind;
|
||||
|
||||
match e.kind() {
|
||||
ErrorKind::UnexpectedEof => Error::MissingData,
|
||||
_ => Error::Io(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Hex deserialization error.
|
||||
|
|
|
@ -361,6 +361,8 @@ impl<D: fmt::Display> serde::de::Expected for DisplayExpected<D> {
|
|||
fn consensus_error_into_serde<E: serde::de::Error>(error: ConsensusError) -> E {
|
||||
match error {
|
||||
ConsensusError::Io(error) => panic!("unexpected IO error {:?}", error),
|
||||
ConsensusError::MissingData =>
|
||||
E::custom("missing data (early end of file or slice too short)"),
|
||||
ConsensusError::OversizedVectorAllocation { requested, max } => E::custom(format_args!(
|
||||
"the requested allocation of {} items exceeds maximum of {}",
|
||||
requested, max
|
||||
|
|
Loading…
Reference in New Issue