zebra_chain/serialization/
error.rs1use std::{array::TryFromSliceError, io, num::TryFromIntError, str::Utf8Error, sync::Arc};
4
5use bounded_vec::BoundedVecOutOfBounds;
6use hex::FromHexError;
7use thiserror::Error;
8
9#[derive(Clone, Error, Debug)]
12pub enum SerializationError {
13 #[error("io error: {0}")]
15 Io(#[from] Arc<io::Error>),
16
17 #[error("parse error: {0}")]
20 Parse(&'static str),
21
22 #[error("string was not UTF-8: {0}")]
26 Utf8Error(#[from] Utf8Error),
27
28 #[error("slice was the wrong length: {0}")]
30 TryFromSliceError(#[from] TryFromSliceError),
31
32 #[error("CompactSize too large: {0}")]
34 TryFromIntError(#[from] TryFromIntError),
35
36 #[error("string was not hex: {0}")]
38 FromHexError(#[from] FromHexError),
39
40 #[error("input couldn't be parsed as a zatoshi `Amount`: {source}")]
42 Amount {
43 #[from]
45 source: crate::amount::Error,
46 },
47
48 #[error("transaction balance is non-zero but doesn't have Sapling shielded spends or outputs")]
53 BadTransactionBalance,
54
55 #[error("script error: {0}")]
57 Script(#[from] zcash_script::script::Error),
58
59 #[error("script opcode error: {0}")]
61 Opcode(#[from] zcash_script::opcode::Error),
62
63 #[error("script number error: {0}")]
65 Num(#[from] zcash_script::num::Error),
66}
67
68impl From<SerializationError> for io::Error {
69 fn from(e: SerializationError) -> Self {
70 match e {
71 SerializationError::Io(e) => {
72 Arc::try_unwrap(e).unwrap_or_else(|e| io::Error::new(e.kind(), e.to_string()))
73 }
74 SerializationError::Parse(msg) => io::Error::new(io::ErrorKind::InvalidData, msg),
75 SerializationError::Utf8Error(e) => io::Error::new(io::ErrorKind::InvalidData, e),
76 SerializationError::TryFromSliceError(e) => {
77 io::Error::new(io::ErrorKind::InvalidData, e)
78 }
79 SerializationError::TryFromIntError(e) => io::Error::new(io::ErrorKind::InvalidData, e),
80 SerializationError::FromHexError(e) => io::Error::new(io::ErrorKind::InvalidData, e),
81 SerializationError::Amount { source } => {
82 io::Error::new(io::ErrorKind::InvalidData, source)
83 }
84 SerializationError::BadTransactionBalance => io::Error::new(
85 io::ErrorKind::InvalidData,
86 "bad transaction balance: non-zero with no Sapling shielded spends or outputs",
87 ),
88 SerializationError::Script(e) => io::Error::new(io::ErrorKind::InvalidData, e),
89 SerializationError::Opcode(e) => io::Error::new(io::ErrorKind::InvalidData, e),
90 SerializationError::Num(e) => io::Error::new(io::ErrorKind::InvalidData, e),
91 }
92 }
93}
94
95impl From<crate::Error> for SerializationError {
96 fn from(e: crate::Error) -> Self {
97 match e {
98 crate::Error::InvalidConsensusBranchId => Self::Parse("invalid consensus branch id"),
99 crate::Error::Io(e) => Self::Io(e),
100 crate::Error::MissingNetworkUpgrade => Self::Parse("missing network upgrade"),
101 crate::Error::Amount(_) => Self::BadTransactionBalance,
102 crate::Error::Conversion(_) => {
103 Self::Parse("Zebra's type could not be converted to its librustzcash equivalent")
104 }
105 }
106 }
107}
108
109impl From<io::Error> for SerializationError {
112 fn from(value: io::Error) -> Self {
113 Arc::new(value).into()
114 }
115}
116
117impl From<BoundedVecOutOfBounds> for SerializationError {
118 fn from(_: BoundedVecOutOfBounds) -> Self {
119 SerializationError::Parse("vector length out of bounds")
120 }
121}