-
Notifications
You must be signed in to change notification settings - Fork 178
Description
Right now our serialization error uses some fairly generic error variants that don't include enough context. For example, recently I ran into a bug in tests for zebra-state where the error was particularly unhelpful
running 1 test
The application panicked (crashed).
Message: called `Result::unwrap()` on an `Err` value: Io(Custom { kind: UnexpectedEof, error: "failed to fill whole buffer" })
Location: /home/jlusby/git/zfnd/zebra/zebra-test/src/transcript.rs:41
So I tweaked the SerializationError type to use a more useful error message and include extra context about what it was trying to deserialize:
running 1 test The application panicked (crashed). Message: called `Result::unwrap()` on an `Err` value: 0: could not serialize zebra_chain::block::hash::BlockHeaderHash 1: failed to fill whole buffer
By making the following changes:
#[derive(Error, Debug)]
pub enum SerializationError {
/// An underlying IO error.
#[error("could not deserialize {1}")]
Io(#[source] io::Error, &'static str),
/// The data to be deserialized was malformed.
// XXX refine errors
#[error("parse error: {0}")]
Parse(&'static str),
/// An error caused when validating a zatoshi `Amount`
#[error("input couldn't be parsed as a zatoshi `Amount`")]
Amount {
/// The source error indicating how the num failed to validate
#[from]
source: crate::types::amount::Error,
},
}followed by a ton of this throughout the code
.map_err(|source| SerializationError::Io(source, std::any::type_name::<Self>()))?However, these changes were very invasive and I ran into some issues with impl Decoder in zebra-network where we're using SerializationError as our error kind and fixing it appropriately was more of a yak shave than I wanted to get into.
Long term we should probably refine these error types. We should probably rename SerializationError to DeserializationError as it is only the error return type for ZcashDeserialize. We should look into giving more context for why a serialization error was thrown, the solution that adds a static str to put the type name in has the advantage of requiring that the context is provided via compiler errors, but its not ideal ergonomically, if we can find a way to require instrumention on all of our deserialize impls it might be better to use SpanTrace to capture the context about what is being deserialized.
For codec we should introduce our own error kind, us implicitly constructing a DeserializeError::Io from errors originating in the tokio codec upstream code misrepresents the meaning of the Io error, which likely has nothing to do with deserialization.