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 internals::write_err;
145        use CompactSizeDecoderErrorInner as E;
146
147        match self.0 {
148            E::UnexpectedEof { required: 1, received: 0 } => {
149                write!(f, "required at least one byte but the input is empty")
150            }
151            E::UnexpectedEof { required, received: 0 } => {
152                write!(f, "required at least {} bytes but the input is empty", required)
153            }
154            E::UnexpectedEof { required, received } => write!(
155                f,
156                "required at least {} bytes but only {} bytes were received",
157                required, received
158            ),
159            E::NonMinimal { value } => write!(f, "the value {} was not encoded minimally", value),
160            E::ValueExceedsLimit(ref e) => write_err!(f, "value exceeds limit"; e),
161        }
162    }
163}
164
165#[cfg(feature = "std")]
166impl std::error::Error for CompactSizeDecoderError {
167    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
168        use CompactSizeDecoderErrorInner as E;
169
170        match self {
171            Self(E::ValueExceedsLimit(ref e)) => Some(e),
172            _ => None,
173        }
174    }
175}
176
177/// The error returned when a compact size value exceeds a configured limit.
178#[derive(Debug, Clone, PartialEq, Eq)]
179pub struct LengthPrefixExceedsMaxError {
180    /// The limit that was exceeded.
181    pub(crate) limit: usize,
182    /// The value that exceeded the limit.
183    pub(crate) value: u64,
184}
185
186impl From<Infallible> for LengthPrefixExceedsMaxError {
187    fn from(never: Infallible) -> Self { match never {} }
188}
189
190impl core::fmt::Display for LengthPrefixExceedsMaxError {
191    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
192        write!(f, "decoded length {} exceeds maximum allowed {}", self.value, self.limit)
193    }
194}
195
196#[cfg(feature = "std")]
197impl std::error::Error for LengthPrefixExceedsMaxError {
198    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
199}
200
201/// The error returned by the [`ByteVecDecoder`].
202#[cfg(feature = "alloc")]
203#[derive(Debug, Clone, PartialEq, Eq)]
204pub struct ByteVecDecoderError(pub(crate) ByteVecDecoderErrorInner);
205
206#[cfg(feature = "alloc")]
207#[derive(Debug, Clone, PartialEq, Eq)]
208pub(crate) enum ByteVecDecoderErrorInner {
209    /// Error decoding the byte vector length prefix.
210    LengthPrefixDecode(CompactSizeDecoderError),
211    /// Not enough bytes given to decoder.
212    UnexpectedEof(UnexpectedEofError),
213}
214
215#[cfg(feature = "alloc")]
216impl From<Infallible> for ByteVecDecoderError {
217    fn from(never: Infallible) -> Self { match never {} }
218}
219
220#[cfg(feature = "alloc")]
221impl fmt::Display for ByteVecDecoderError {
222    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
223        use ByteVecDecoderErrorInner as E;
224
225        match self.0 {
226            E::LengthPrefixDecode(ref e) => write_err!(f, "byte vec decoder error"; e),
227            E::UnexpectedEof(ref e) => write_err!(f, "byte vec decoder error"; e),
228        }
229    }
230}
231
232#[cfg(feature = "alloc")]
233#[cfg(feature = "std")]
234impl std::error::Error for ByteVecDecoderError {
235    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
236        use ByteVecDecoderErrorInner as E;
237
238        match self.0 {
239            E::LengthPrefixDecode(ref e) => Some(e),
240            E::UnexpectedEof(ref e) => Some(e),
241        }
242    }
243}
244
245/// The error returned by the [`VecDecoder`].
246#[cfg(feature = "alloc")]
247#[derive(Debug, Clone, PartialEq, Eq)]
248pub struct VecDecoderError<Err>(pub(crate) VecDecoderErrorInner<Err>);
249
250#[cfg(feature = "alloc")]
251#[derive(Debug, Clone, PartialEq, Eq)]
252pub(crate) enum VecDecoderErrorInner<Err> {
253    /// Error decoding the vector length prefix.
254    LengthPrefixDecode(CompactSizeDecoderError),
255    /// Error while decoding an item.
256    Item(Err),
257    /// Not enough bytes given to decoder.
258    UnexpectedEof(UnexpectedEofError),
259}
260
261#[cfg(feature = "alloc")]
262impl<Err> From<Infallible> for VecDecoderError<Err> {
263    fn from(never: Infallible) -> Self { match never {} }
264}
265
266#[cfg(feature = "alloc")]
267impl<Err> fmt::Display for VecDecoderError<Err>
268where
269    Err: fmt::Display + fmt::Debug,
270{
271    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
272        use VecDecoderErrorInner as E;
273
274        match self.0 {
275            E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
276            E::Item(ref e) => write_err!(f, "vec decoder error"; e),
277            E::UnexpectedEof(ref e) => write_err!(f, "vec decoder error"; e),
278        }
279    }
280}
281
282#[cfg(feature = "std")]
283impl<Err> std::error::Error for VecDecoderError<Err>
284where
285    Err: std::error::Error + 'static,
286{
287    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
288        use VecDecoderErrorInner as E;
289
290        match self.0 {
291            E::LengthPrefixDecode(ref e) => Some(e),
292            E::Item(ref e) => Some(e),
293            E::UnexpectedEof(ref e) => Some(e),
294        }
295    }
296}
297
298/// Not enough bytes given to decoder.
299#[derive(Debug, Clone, PartialEq, Eq)]
300pub struct UnexpectedEofError {
301    /// Number of bytes missing to complete decoder.
302    pub(crate) missing: usize,
303}
304
305impl From<Infallible> for UnexpectedEofError {
306    fn from(never: Infallible) -> Self { match never {} }
307}
308
309impl fmt::Display for UnexpectedEofError {
310    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311        write!(f, "not enough bytes for decoder, {} more bytes required", self.missing)
312    }
313}
314
315#[cfg(feature = "std")]
316impl std::error::Error for UnexpectedEofError {
317    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
318}
319
320/// Helper macro to define an error type for a `DecoderN`.
321macro_rules! define_decoder_n_error {
322    (
323        $(#[$attr:meta])*
324        $name:ident;
325        $(
326            $(#[$err_attr:meta])*
327            ($err_wrap:ident, $err_type:ident, $err_msg:literal),
328        )*
329    ) => {
330        $(#[$attr])*
331        #[derive(Debug, Clone, PartialEq, Eq)]
332        pub enum $name<$($err_type,)*> {
333            $(
334                $(#[$err_attr])*
335                $err_wrap($err_type),
336            )*
337        }
338
339        impl<$($err_type,)*> fmt::Display for $name<$($err_type,)*>
340        where
341            $($err_type: fmt::Display,)*
342        {
343            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
344                match self {
345                    $(Self::$err_wrap(ref e) => write_err!(f, $err_msg; e),)*
346                }
347            }
348        }
349
350        #[cfg(feature = "std")]
351        impl<$($err_type,)*> std::error::Error for $name<$($err_type,)*>
352        where
353            $($err_type: std::error::Error + 'static,)*
354        {
355            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
356                match self {
357                    $(Self::$err_wrap(ref e) => Some(e),)*
358                }
359            }
360        }
361    };
362}
363
364define_decoder_n_error! {
365    /// Error type for [`Decoder2`].
366    Decoder2Error;
367    /// Error from the first decoder.
368    (First, A, "first decoder error."),
369    /// Error from the second decoder.
370    (Second, B, "second decoder error."),
371}
372
373define_decoder_n_error! {
374    /// Error type for [`Decoder3`].
375    Decoder3Error;
376    /// Error from the first decoder.
377    (First, A, "first decoder error."),
378    /// Error from the second decoder.
379    (Second, B, "second decoder error."),
380    /// Error from the third decoder.
381    (Third, C, "third decoder error."),
382}
383
384define_decoder_n_error! {
385    /// Error type for [`Decoder4`].
386    Decoder4Error;
387    /// Error from the first decoder.
388    (First, A, "first decoder error."),
389    /// Error from the second decoder.
390    (Second, B, "second decoder error."),
391    /// Error from the third decoder.
392    (Third, C, "third decoder error."),
393    /// Error from the fourth decoder.
394    (Fourth, D, "fourth decoder error."),
395}
396
397define_decoder_n_error! {
398    /// Error type for [`Decoder6`].
399    Decoder6Error;
400    /// Error from the first decoder.
401    (First, A, "first decoder error."),
402    /// Error from the second decoder.
403    (Second, B, "second decoder error."),
404    /// Error from the third decoder.
405    (Third, C, "third decoder error."),
406    /// Error from the fourth decoder.
407    (Fourth, D, "fourth decoder error."),
408    /// Error from the fifth decoder.
409    (Fifth, E, "fifth decoder error."),
410    /// Error from the sixth decoder.
411    (Sixth, F, "sixth decoder error."),
412}