coap_lite/
error.rs

1//! The errors of the `coap` module.
2
3use alloc::{
4    borrow::ToOwned,
5    string::{String, ToString},
6};
7use core::{fmt, num::TryFromIntError};
8#[cfg(feature = "std")]
9use std::error;
10
11use crate::ResponseType;
12
13/// The errors that can occur when encoding/decoding packets.
14#[derive(Debug, PartialEq)]
15pub enum MessageError {
16    InvalidHeader,
17    InvalidPacketLength,
18    InvalidTokenLength,
19    InvalidOptionDelta,
20    InvalidOptionLength,
21}
22
23impl fmt::Display for MessageError {
24    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25        match self {
26            MessageError::InvalidHeader => {
27                write!(f, "CoAP error: invalid header")
28            }
29            MessageError::InvalidPacketLength => {
30                write!(f, "CoAP error: invalid packet length, consider using BlockHandler")
31            }
32            MessageError::InvalidTokenLength => {
33                write!(f, "CoAP error: invalid token length")
34            }
35            MessageError::InvalidOptionDelta => {
36                write!(f, "CoAP error: invalid option delta")
37            }
38            MessageError::InvalidOptionLength => {
39                write!(f, "CoAP error: invalid option length")
40            }
41        }
42    }
43}
44
45#[cfg(feature = "std")]
46impl error::Error for MessageError {}
47
48/// The error that can occur when parsing a content-format.
49#[derive(Debug, PartialEq)]
50pub struct InvalidContentFormat;
51
52impl fmt::Display for InvalidContentFormat {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        write!(f, "CoAP error: invalid content-format number")
55    }
56}
57
58#[cfg(feature = "std")]
59impl error::Error for InvalidContentFormat {}
60
61/// The error that can occur when parsing an observe option value.
62#[derive(Debug, PartialEq)]
63pub struct InvalidObserve;
64
65impl fmt::Display for InvalidObserve {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        write!(f, "CoAP error: invalid observe option number")
68    }
69}
70
71#[cfg(feature = "std")]
72impl error::Error for InvalidObserve {}
73
74/// The error that can occur when parsing an option value.
75#[derive(Debug, PartialEq)]
76pub struct IncompatibleOptionValueFormat {
77    pub message: String,
78}
79
80impl fmt::Display for IncompatibleOptionValueFormat {
81    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82        write!(f, "Incompatible option value: {}", self.message)
83    }
84}
85
86#[cfg(feature = "std")]
87impl error::Error for IncompatibleOptionValueFormat {}
88
89/// The errors that can occur when constructing a new block value.
90#[derive(Debug, PartialEq)]
91pub enum InvalidBlockValue {
92    SizeExponentEncodingError(usize),
93    TypeBoundsError(TryFromIntError),
94}
95
96impl fmt::Display for InvalidBlockValue {
97    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98        match self {
99            InvalidBlockValue::SizeExponentEncodingError(size) => {
100                write!(f, "size cannot be encoded {}", size)
101            }
102            InvalidBlockValue::TypeBoundsError(err) => {
103                write!(f, "size provided is outside type bounds: {}", err)
104            }
105        }
106    }
107}
108
109#[cfg(feature = "std")]
110impl error::Error for InvalidBlockValue {}
111
112/// Participatory mechanism for the low-level library to communicate to callers
113/// that unexpected errors occurred while handling standard parts of the
114/// protocol that should ideally deliver a failure message to the peer. But
115/// rather than apply that response message ourselves we yield this error and
116/// ask the caller to perform the conversion.  For convenience, this can be
117/// done with [`crate::CoapRequest::apply_from_error`].
118#[derive(Debug, Clone)]
119pub struct HandlingError {
120    pub code: Option<ResponseType>,
121    pub message: String,
122}
123
124impl fmt::Display for HandlingError {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        write!(f, "Handling error {:?}: {}", self.code, self.message)
127    }
128}
129
130#[cfg(feature = "std")]
131impl error::Error for HandlingError {}
132
133impl HandlingError {
134    pub fn not_handled() -> Self {
135        Self {
136            code: None,
137            message: "Not handled".to_owned(),
138        }
139    }
140
141    pub fn not_found() -> Self {
142        Self::with_code(ResponseType::NotFound, "Not found")
143    }
144
145    pub fn bad_request<T: ToString>(e: T) -> Self {
146        Self::with_code(ResponseType::BadRequest, e)
147    }
148
149    pub fn internal<T: ToString>(e: T) -> Self {
150        Self::with_code(ResponseType::InternalServerError, e)
151    }
152
153    pub fn method_not_supported() -> Self {
154        Self::with_code(ResponseType::MethodNotAllowed, "Method not supported")
155    }
156
157    pub fn with_code<T: ToString>(code: ResponseType, e: T) -> Self {
158        Self {
159            code: Some(code),
160            message: e.to_string(),
161        }
162    }
163}