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)> {
114        let Self() = self;
115        None
116    }
117}
118
119/// An error consensus decoding a compact size encoded integer.
120#[derive(Debug, Clone, PartialEq, Eq)]
121pub struct CompactSizeDecoderError(pub(crate) CompactSizeDecoderErrorInner);
122
123#[derive(Debug, Clone, PartialEq, Eq)]
124pub(crate) enum CompactSizeDecoderErrorInner {
125    /// Returned when the decoder reaches end of stream (EOF).
126    UnexpectedEof {
127        /// How many bytes were required.
128        required: usize,
129        /// How many bytes were received.
130        received: usize,
131    },
132    /// Returned when the encoding is not minimal
133    NonMinimal {
134        /// The encoded value.
135        value: u64,
136    },
137    /// Returned when the encoded value exceeds the decoder's limit.
138    ValueExceedsLimit(LengthPrefixExceedsMaxError),
139}
140
141impl From<Infallible> for CompactSizeDecoderError {
142    fn from(never: Infallible) -> Self { match never {} }
143}
144
145impl core::fmt::Display for CompactSizeDecoderError {
146    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
147        use CompactSizeDecoderErrorInner as E;
148
149        match self.0 {
150            E::UnexpectedEof { required: 1, received: 0 } => {
151                write!(f, "required at least one byte but the input is empty")
152            }
153            E::UnexpectedEof { required, received: 0 } => {
154                write!(f, "required at least {} bytes but the input is empty", required)
155            }
156            E::UnexpectedEof { required, received } => write!(
157                f,
158                "required at least {} bytes but only {} bytes were received",
159                required, received
160            ),
161            E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
162            E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
163        }
164    }
165}
166
167#[cfg(feature = "std")]
168impl std::error::Error for CompactSizeDecoderError {
169    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
170        use CompactSizeDecoderErrorInner as E;
171
172        match self {
173            Self(E::ValueExceedsLimit(ref e)) => Some(e),
174            _ => None,
175        }
176    }
177}
178
179/// The error returned when a compact size value exceeds a configured limit.
180#[derive(Debug, Clone, PartialEq, Eq)]
181pub struct LengthPrefixExceedsMaxError {
182    /// The limit that was exceeded.
183    pub(crate) limit: usize,
184    /// The value that exceeded the limit.
185    pub(crate) value: u64,
186}
187
188impl From<Infallible> for LengthPrefixExceedsMaxError {
189    fn from(never: Infallible) -> Self { match never {} }
190}
191
192impl core::fmt::Display for LengthPrefixExceedsMaxError {
193    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
194        write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
195    }
196}
197
198#[cfg(feature = "std")]
199impl std::error::Error for LengthPrefixExceedsMaxError {
200    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
201        let Self { limit: _, value: _ } = self;
202        None
203    }
204}
205
206/// The error returned by the [`ByteVecDecoder`].
207#[cfg(feature = "alloc")]
208#[derive(Debug, Clone, PartialEq, Eq)]
209pub struct ByteVecDecoderError(pub(crate) ByteVecDecoderErrorInner);
210
211#[cfg(feature = "alloc")]
212#[derive(Debug, Clone, PartialEq, Eq)]
213pub(crate) enum ByteVecDecoderErrorInner {
214    /// Error decoding the byte vector length prefix.
215    LengthPrefixDecode(CompactSizeDecoderError),
216    /// Not enough bytes given to decoder.
217    UnexpectedEof(UnexpectedEofError),
218}
219
220#[cfg(feature = "alloc")]
221impl From<Infallible> for ByteVecDecoderError {
222    fn from(never: Infallible) -> Self { match never {} }
223}
224
225#[cfg(feature = "alloc")]
226impl fmt::Display for ByteVecDecoderError {
227    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
228        use ByteVecDecoderErrorInner as E;
229
230        match self.0 {
231            E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
232            E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
233        }
234    }
235}
236
237#[cfg(feature = "alloc")]
238#[cfg(feature = "std")]
239impl std::error::Error for ByteVecDecoderError {
240    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
241        use ByteVecDecoderErrorInner as E;
242
243        match self.0 {
244            E::LengthPrefixDecode(ref e) => Some(e),
245            E::UnexpectedEof(ref e) => Some(e),
246        }
247    }
248}
249
250/// The error returned by the [`VecDecoder`].
251#[cfg(feature = "alloc")]
252#[derive(Debug, Clone, PartialEq, Eq)]
253pub struct VecDecoderError<Err>(pub(crate) VecDecoderErrorInner<Err>);
254
255#[cfg(feature = "alloc")]
256#[derive(Debug, Clone, PartialEq, Eq)]
257pub(crate) enum VecDecoderErrorInner<Err> {
258    /// Error decoding the vector length prefix.
259    LengthPrefixDecode(CompactSizeDecoderError),
260    /// Error while decoding an item.
261    Item(Err),
262    /// Not enough bytes given to decoder.
263    UnexpectedEof(UnexpectedEofError),
264}
265
266#[cfg(feature = "alloc")]
267impl<Err> From<Infallible> for VecDecoderError<Err> {
268    fn from(never: Infallible) -> Self { match never {} }
269}
270
271#[cfg(feature = "alloc")]
272impl<Err> fmt::Display for VecDecoderError<Err>
273where
274    Err: fmt::Display + fmt::Debug,
275{
276    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277        use VecDecoderErrorInner as E;
278
279        match self.0 {
280            E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
281            E::Item(ref e) => write_err!(f, "vec decoder error"; e),
282            E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
283        }
284    }
285}
286
287#[cfg(feature = "std")]
288impl<Err> std::error::Error for VecDecoderError<Err>
289where
290    Err: std::error::Error + 'static,
291{
292    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
293        use VecDecoderErrorInner as E;
294
295        match self.0 {
296            E::LengthPrefixDecode(ref e) => Some(e),
297            E::Item(ref e) => Some(e),
298            E::UnexpectedEof(ref e) => Some(e),
299        }
300    }
301}
302
303/// Not enough bytes given to decoder.
304#[derive(Debug, Clone, PartialEq, Eq)]
305pub struct UnexpectedEofError {
306    /// Number of bytes missing to complete decoder.
307    pub(crate) missing: usize,
308}
309
310impl From<Infallible> for UnexpectedEofError {
311    fn from(never: Infallible) -> Self { match never {} }
312}
313
314impl fmt::Display for UnexpectedEofError {
315    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316        write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
317    }
318}
319
320#[cfg(feature = "std")]
321impl std::error::Error for UnexpectedEofError {
322    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
323        let Self { missing: _ } = self;
324        None
325    }
326}
327
328/// An error that can occur when decoding from a hex string.
329#[cfg(feature = "hex")]
330#[derive(Debug, Clone, PartialEq, Eq)]
331pub struct FromHexError<ParseErr>(pub(crate) FromHexErrorInner<ParseErr>);
332
333#[cfg(feature = "hex")]
334#[derive(Debug, Clone, PartialEq, Eq)]
335pub(crate) enum FromHexErrorInner<ParseErr> {
336    /// The hex string had an odd number of characters.
337    OddLength(hex::OddLengthStringError),
338    /// A character in the hex string was not a valid hex digit.
339    InvalidChar(hex::InvalidCharError),
340    /// The decoder rejected the decoded bytes, or bytes remained unconsumed after decoding.
341    Decode(DecodeError<ParseErr>),
342}
343
344#[cfg(feature = "hex")]
345impl<ParseErr> From<Infallible> for FromHexError<ParseErr> {
346    fn from(never: Infallible) -> Self { match never {} }
347}
348
349#[cfg(feature = "hex")]
350impl<ParseErr: fmt::Display> fmt::Display for FromHexError<ParseErr> {
351    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
352        match self.0 {
353            FromHexErrorInner::OddLength(ref e) => write_err!(f, "odd length string"; e),
354            FromHexErrorInner::InvalidChar(ref e) => write_err!(f, "invalid character"; e),
355            FromHexErrorInner::Decode(ref e) => write_err!(f, "decode error"; e),
356        }
357    }
358}
359
360#[cfg(feature = "hex")]
361#[cfg(feature = "std")]
362impl<ParseErr> std::error::Error for FromHexError<ParseErr>
363where
364    ParseErr: std::error::Error + 'static,
365{
366    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
367        match self.0 {
368            FromHexErrorInner::OddLength(ref e) => Some(e),
369            FromHexErrorInner::InvalidChar(ref e) => Some(e),
370            FromHexErrorInner::Decode(ref e) => Some(e),
371        }
372    }
373}
374
375/// Helper macro to define an error type for a `DecoderN`.
376macro_rules! define_decoder_n_error {
377    (
378        $(#[$attr:meta])*
379        $name:ident;
380        $(
381            $(#[$err_attr:meta])*
382            ($err_wrap:ident, $err_type:ident, $err_msg:literal),
383        )*
384    ) => {
385        $(#[$attr])*
386        #[derive(Debug, Clone, PartialEq, Eq)]
387        pub enum $name<$($err_type,)*> {
388            $(
389                $(#[$err_attr])*
390                $err_wrap($err_type),
391            )*
392        }
393
394        impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
395        where
396            $($err_type: fmt::Display,)*
397        {
398            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
399                match self {
400                    $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
401                }
402            }
403        }
404
405        #[cfg(feature = "std")]
406        impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
407        where
408            $($err_type: std::error::Error + 'static,)*
409        {
410            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
411                match self {
412                    $(Self::$err_wrap(ref e) => Some(e),)*
413                }
414            }
415        }
416    };
417}
418
419define_decoder_n_error! {
420    /// Error type for [`Decoder2`].
421    Decoder2Error;
422    /// Error from the first decoder.
423    (First, A, "first decoder error."),
424    /// Error from the second decoder.
425    (Second, B, "second decoder error."),
426}
427
428define_decoder_n_error! {
429    /// Error type for [`Decoder3`].
430    Decoder3Error;
431    /// Error from the first decoder.
432    (First, A, "first decoder error."),
433    /// Error from the second decoder.
434    (Second, B, "second decoder error."),
435    /// Error from the third decoder.
436    (Third, C, "third decoder error."),
437}
438
439define_decoder_n_error! {
440    /// Error type for [`Decoder4`].
441    Decoder4Error;
442    /// Error from the first decoder.
443    (First, A, "first decoder error."),
444    /// Error from the second decoder.
445    (Second, B, "second decoder error."),
446    /// Error from the third decoder.
447    (Third, C, "third decoder error."),
448    /// Error from the fourth decoder.
449    (Fourth, D, "fourth decoder error."),
450}
451
452define_decoder_n_error! {
453    /// Error type for [`Decoder6`].
454    Decoder6Error;
455    /// Error from the first decoder.
456    (First, A, "first decoder error."),
457    /// Error from the second decoder.
458    (Second, B, "second decoder error."),
459    /// Error from the third decoder.
460    (Third, C, "third decoder error."),
461    /// Error from the fourth decoder.
462    (Fourth, D, "fourth decoder error."),
463    /// Error from the fifth decoder.
464    (Fifth, E, "fifth decoder error."),
465    /// Error from the sixth decoder.
466    (Sixth, F, "sixth decoder error."),
467}