Skip to main content

bitcoin_consensus_encoding/
error.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Error types for the whole crate.
4//!
5//! All error types are publicly available at the crate root.
6// We separate them into a module so the HTML docs are less cluttered.
7
8use core::convert::Infallible;
9use core::fmt;
10
11use internals::write_err;
12
13#[cfg(doc)]
14use crate::{ArrayDecoder, Decoder2, Decoder3, Decoder4, Decoder6};
15#[cfg(feature = "alloc")]
16#[cfg(doc)]
17use crate::{ByteVecDecoder, VecDecoder};
18
19/// An error that can occur when reading and decoding from a buffered reader.
20#[cfg(feature = "std")]
21#[derive(Debug)]
22pub enum ReadError<D> {
23    /// An I/O error occurred while reading from the reader.
24    Io(std::io::Error),
25    /// The decoder encountered an error while parsing the data.
26    Decode(D),
27}
28
29#[cfg(feature = "std")]
30impl<D: core::fmt::Display> core::fmt::Display for ReadError<D> {
31    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32        match self {
33            Self::Io(e) => write!(f, "I/O error: {}", e),
34            Self::Decode(e) => write!(f, "decode error: {}", e),
35        }
36    }
37}
38
39#[cfg(feature = "std")]
40impl<D> std::error::Error for ReadError<D>
41where
42    D: std::error::Error + 'static,
43{
44    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
45        match self {
46            Self::Io(e) => Some(e),
47            Self::Decode(e) => Some(e),
48        }
49    }
50}
51
52#[cfg(feature = "std")]
53impl<D> From<std::io::Error> for ReadError<D> {
54    fn from(e: std::io::Error) -> Self { Self::Io(e) }
55}
56
57/// An error that can occur when decoding from a byte slice.
58#[derive(Debug, Clone, Eq, PartialEq)]
59pub enum DecodeError<Err> {
60    /// Provided slice failed to correctly decode as a type.
61    Parse(Err),
62    /// Bytes remained unconsumed after completing decoding.
63    Unconsumed(UnconsumedError),
64}
65
66impl<Err> From<Infallible> for DecodeError<Err> {
67    fn from(never: Infallible) -> Self { match never {} }
68}
69
70impl<Err> fmt::Display for DecodeError<Err>
71where
72    Err: fmt::Display,
73{
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        match self {
76            Self::Parse(ref e) => write_err!(f, "error parsing encoded object"; e),
77            Self::Unconsumed(ref e) => write_err!(f, "unconsumed"; e),
78        }
79    }
80}
81
82#[cfg(feature = "std")]
83impl<Err> std::error::Error for DecodeError<Err>
84where
85    Err: std::error::Error + 'static,
86{
87    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
88        match self {
89            Self::Parse(ref e) => Some(e),
90            Self::Unconsumed(ref e) => Some(e),
91        }
92    }
93}
94
95/// Bytes remained unconsumed after completing decoding.
96// This is just to give us the ability to add details in a
97// non-breaking way if we want to at some stage.
98#[derive(Debug, Clone, Eq, PartialEq)]
99pub struct UnconsumedError();
100
101impl From<Infallible> for UnconsumedError {
102    fn from(never: Infallible) -> Self { match never {} }
103}
104
105impl fmt::Display for UnconsumedError {
106    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107        write!(f, "data not consumed entirely when decoding")
108    }
109}
110
111#[cfg(feature = "std")]
112impl std::error::Error for UnconsumedError {
113    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
114}
115
116/// An error consensus decoding a compact size encoded integer.
117#[derive(Debug, Clone, PartialEq, Eq)]
118pub struct CompactSizeDecoderError(pub(crate) CompactSizeDecoderErrorInner);
119
120#[derive(Debug, Clone, PartialEq, Eq)]
121pub(crate) enum CompactSizeDecoderErrorInner {
122    /// Returned when the decoder reaches end of stream (EOF).
123    UnexpectedEof {
124        /// How many bytes were required.
125        required: usize,
126        /// How many bytes were received.
127        received: usize,
128    },
129    /// Returned when the encoding is not minimal
130    NonMinimal {
131        /// The encoded value.
132        value: u64,
133    },
134    /// Returned when the encoded value exceeds the decoder's limit.
135    ValueExceedsLimit(LengthPrefixExceedsMaxError),
136}
137
138impl From<Infallible> for CompactSizeDecoderError {
139    fn from(never: Infallible) -> Self { match never {} }
140}
141
142impl core::fmt::Display for CompactSizeDecoderError {
143    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
144        use CompactSizeDecoderErrorInner as E;
145
146        match self.0 {
147            E::UnexpectedEof { required: 1, received: 0 } => {
148                write!(f, "required at least one byte but the input is empty")
149            }
150            E::UnexpectedEof { required, received: 0 } => {
151                write!(f, "required at least {} bytes but the input is empty", required)
152            }
153            E::UnexpectedEof { required, received } => write!(
154                f,
155                "required at least {} bytes but only {} bytes were received",
156                required, received
157            ),
158            E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
159            E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
160        }
161    }
162}
163
164#[cfg(feature = "std")]
165impl std::error::Error for CompactSizeDecoderError {
166    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
167        use CompactSizeDecoderErrorInner as E;
168
169        match self {
170            Self(E::ValueExceedsLimit(ref e)) => Some(e),
171            _ => None,
172        }
173    }
174}
175
176/// The error returned when a compact size value exceeds a configured limit.
177#[derive(Debug, Clone, PartialEq, Eq)]
178pub struct LengthPrefixExceedsMaxError {
179    /// The limit that was exceeded.
180    pub(crate) limit: usize,
181    /// The value that exceeded the limit.
182    pub(crate) value: u64,
183}
184
185impl From<Infallible> for LengthPrefixExceedsMaxError {
186    fn from(never: Infallible) -> Self { match never {} }
187}
188
189impl core::fmt::Display for LengthPrefixExceedsMaxError {
190    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
191        write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
192    }
193}
194
195#[cfg(feature = "std")]
196impl std::error::Error for LengthPrefixExceedsMaxError {
197    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
198}
199
200/// The error returned by the [`ByteVecDecoder`].
201#[cfg(feature = "alloc")]
202#[derive(Debug, Clone, PartialEq, Eq)]
203pub struct ByteVecDecoderError(pub(crate) ByteVecDecoderErrorInner);
204
205#[cfg(feature = "alloc")]
206#[derive(Debug, Clone, PartialEq, Eq)]
207pub(crate) enum ByteVecDecoderErrorInner {
208    /// Error decoding the byte vector length prefix.
209    LengthPrefixDecode(CompactSizeDecoderError),
210    /// Not enough bytes given to decoder.
211    UnexpectedEof(UnexpectedEofError),
212}
213
214#[cfg(feature = "alloc")]
215impl From<Infallible> for ByteVecDecoderError {
216    fn from(never: Infallible) -> Self { match never {} }
217}
218
219#[cfg(feature = "alloc")]
220impl fmt::Display for ByteVecDecoderError {
221    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222        use ByteVecDecoderErrorInner as E;
223
224        match self.0 {
225            E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
226            E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
227        }
228    }
229}
230
231#[cfg(feature = "alloc")]
232#[cfg(feature = "std")]
233impl std::error::Error for ByteVecDecoderError {
234    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
235        use ByteVecDecoderErrorInner as E;
236
237        match self.0 {
238            E::LengthPrefixDecode(ref e) => Some(e),
239            E::UnexpectedEof(ref e) => Some(e),
240        }
241    }
242}
243
244/// The error returned by the [`VecDecoder`].
245#[cfg(feature = "alloc")]
246#[derive(Debug, Clone, PartialEq, Eq)]
247pub struct VecDecoderError<Err>(pub(crate) VecDecoderErrorInner<Err>);
248
249#[cfg(feature = "alloc")]
250#[derive(Debug, Clone, PartialEq, Eq)]
251pub(crate) enum VecDecoderErrorInner<Err> {
252    /// Error decoding the vector length prefix.
253    LengthPrefixDecode(CompactSizeDecoderError),
254    /// Error while decoding an item.
255    Item(Err),
256    /// Not enough bytes given to decoder.
257    UnexpectedEof(UnexpectedEofError),
258}
259
260#[cfg(feature = "alloc")]
261impl<Err> From<Infallible> for VecDecoderError<Err> {
262    fn from(never: Infallible) -> Self { match never {} }
263}
264
265#[cfg(feature = "alloc")]
266impl<Err> fmt::Display for VecDecoderError<Err>
267where
268    Err: fmt::Display + fmt::Debug,
269{
270    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271        use VecDecoderErrorInner as E;
272
273        match self.0 {
274            E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
275            E::Item(ref e) => write_err!(f, "vec decoder error"; e),
276            E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
277        }
278    }
279}
280
281#[cfg(feature = "std")]
282impl<Err> std::error::Error for VecDecoderError<Err>
283where
284    Err: std::error::Error + 'static,
285{
286    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
287        use VecDecoderErrorInner as E;
288
289        match self.0 {
290            E::LengthPrefixDecode(ref e) => Some(e),
291            E::Item(ref e) => Some(e),
292            E::UnexpectedEof(ref e) => Some(e),
293        }
294    }
295}
296
297/// Not enough bytes given to decoder.
298#[derive(Debug, Clone, PartialEq, Eq)]
299pub struct UnexpectedEofError {
300    /// Number of bytes missing to complete decoder.
301    pub(crate) missing: usize,
302}
303
304impl From<Infallible> for UnexpectedEofError {
305    fn from(never: Infallible) -> Self { match never {} }
306}
307
308impl fmt::Display for UnexpectedEofError {
309    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310        write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
311    }
312}
313
314#[cfg(feature = "std")]
315impl std::error::Error for UnexpectedEofError {
316    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
317}
318
319/// Helper macro to define an error type for a `DecoderN`.
320macro_rules! define_decoder_n_error {
321    (
322        $(#[$attr:meta])*
323        $name:ident;
324        $(
325            $(#[$err_attr:meta])*
326            ($err_wrap:ident, $err_type:ident, $err_msg:literal),
327        )*
328    ) => {
329        $(#[$attr])*
330        #[derive(Debug, Clone, PartialEq, Eq)]
331        pub enum $name<$($err_type,)*> {
332            $(
333                $(#[$err_attr])*
334                $err_wrap($err_type),
335            )*
336        }
337
338        impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
339        where
340            $($err_type: fmt::Display,)*
341        {
342            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
343                match self {
344                    $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
345                }
346            }
347        }
348
349        #[cfg(feature = "std")]
350        impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
351        where
352            $($err_type: std::error::Error + 'static,)*
353        {
354            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
355                match self {
356                    $(Self::$err_wrap(ref e) => Some(e),)*
357                }
358            }
359        }
360    };
361}
362
363define_decoder_n_error! {
364    /// Error type for [`Decoder2`].
365    Decoder2Error;
366    /// Error from the first decoder.
367    (First, A, "first decoder error."),
368    /// Error from the second decoder.
369    (Second, B, "second decoder error."),
370}
371
372define_decoder_n_error! {
373    /// Error type for [`Decoder3`].
374    Decoder3Error;
375    /// Error from the first decoder.
376    (First, A, "first decoder error."),
377    /// Error from the second decoder.
378    (Second, B, "second decoder error."),
379    /// Error from the third decoder.
380    (Third, C, "third decoder error."),
381}
382
383define_decoder_n_error! {
384    /// Error type for [`Decoder4`].
385    Decoder4Error;
386    /// Error from the first decoder.
387    (First, A, "first decoder error."),
388    /// Error from the second decoder.
389    (Second, B, "second decoder error."),
390    /// Error from the third decoder.
391    (Third, C, "third decoder error."),
392    /// Error from the fourth decoder.
393    (Fourth, D, "fourth decoder error."),
394}
395
396define_decoder_n_error! {
397    /// Error type for [`Decoder6`].
398    Decoder6Error;
399    /// Error from the first decoder.
400    (First, A, "first decoder error."),
401    /// Error from the second decoder.
402    (Second, B, "second decoder error."),
403    /// Error from the third decoder.
404    (Third, C, "third decoder error."),
405    /// Error from the fourth decoder.
406    (Fourth, D, "fourth decoder error."),
407    /// Error from the fifth decoder.
408    (Fifth, E, "fifth decoder error."),
409    /// Error from the sixth decoder.
410    (Sixth, F, "sixth decoder error."),
411}