libcoap_rs/
error.rs

1// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright © The libcoap-rs Contributors, all rights reserved.
4 * This file is part of the libcoap-rs project, see the README file for
5 * general information on this project and the NOTICE.md and LICENSE files
6 * for information regarding copyright ownership and terms of use.
7 *
8 * error.rs - CoAP error types.
9 */
10
11//! Error types
12
13use std::{ffi::NulError, string::FromUtf8Error, sync::PoisonError};
14
15use thiserror::Error;
16
17use crate::protocol::{CoapMessageType, CoapOptionType};
18
19#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
20pub enum MulticastGroupJoinError {
21    /// Unknown error inside of libcoap
22    #[error("CoAP join multicast group error: unknown error in call to libcoap")]
23    Unknown,
24}
25
26#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
27pub enum MulticastHopLimitError {
28    /// Unknown error inside of libcoap
29    #[error("CoAP multicast hop limit error: unable to set hop limit for multicast")]
30    Unknown,
31}
32
33#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
34pub enum EndpointCreationError {
35    /// Unknown error inside of libcoap
36    #[error("CoAP endpoint creation error: unknown error in call to libcoap")]
37    Unknown,
38}
39
40#[cfg(feature = "oscore")]
41#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
42pub enum OscoreConfigError {
43    /// Tried to get oscore config as raw struct which has been invalidated before
44    #[error("Oscore config error: tried to get oscore config as raw struct which has been invalidated before")]
45    Invalid,
46    /// Unknown error inside of libcoap, probably due to missing/invalid entries in your oscore
47    /// config
48    #[error("Oscore config error: unknown error in call to libcoap, probably due to missing/invalid entries in your oscore config")]
49    Unknown,
50}
51
52#[cfg(feature = "oscore")]
53#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
54pub enum OscoreServerCreationError {
55    /// Oscore config seems to be invalid, make sure to use it only once
56    #[error("Oscore server creation error: oscore config seems to be invalid, make sure to use it only once")]
57    OscoreConfigInvalid(#[from] OscoreConfigError),
58    /// Unknown error inside of libcoap
59    #[error("Oscore server creation error: unknown error in call to libcoap")]
60    Unknown,
61}
62
63#[cfg(feature = "oscore")]
64#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
65pub enum OscoreRecipientError {
66    /// Method is called on a context without appropriate oscore information
67    #[error("Oscore recipient error: context is missing appropriate oscore information")]
68    NoOscoreContext,
69    /// Tried adding duplicate recipient to context
70    #[error("Oscore recipient error: tried adding duplicate recipient to context")]
71    DuplicateId,
72    /// Tried removing a recipient that is not associated with the context
73    #[error("Oscore recipient error: tried removing a recipient that is not associated with the context")]
74    NotFound,
75    /// Unknown error inside of libcoap, adding/removing a recipient failed
76    #[error("Oscore recipient error: unknown error in call to libcoap, adding/removing the recipient failed")]
77    Unknown,
78}
79
80#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
81pub enum ContextConfigurationError {
82    /// Unknown error inside of libcoap
83    #[error("CoAP context configuration error: unknown error in call to libcoap")]
84    Unknown,
85    #[error(
86        "CoAP context configuration error: attempted to set encryption context while one has already been configured for this encryption variant"
87    )]
88    CryptoContextAlreadySet,
89}
90
91#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
92pub enum MessageCreationError {
93    /// Unknown error inside of libcoap
94    #[error("CoAP message creation error: unknown error in call to libcoap")]
95    Unknown,
96}
97
98#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
99pub enum IoProcessError {
100    /// Unknown error inside of libcoap
101    #[error("CoAP IO error: unknown error in call to libcoap")]
102    Unknown,
103}
104
105#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
106pub enum SessionGetAppDataError {
107    /// Stored application data type differs from requested type
108    #[error("CoAP application data retrieval error: wrong type")]
109    WrongType,
110}
111
112#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
113pub enum OptionCreationError {
114    /// Unknown error inside of libcoap
115    #[error("CoAP option creation error: unknown error in call to libcoap")]
116    Unknown,
117}
118
119#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
120pub enum SessionCreationError {
121    /// Unknown error inside of libcoap
122    #[error("CoAP session creation error: unknown error in call to libcoap")]
123    Unknown,
124    /// Oscore config seems to be invalid, make sure to use it only once
125    #[cfg(feature = "oscore")]
126    #[error("CoAP session creation error: oscore config seems to be invalid, make sure to use it only once")]
127    OscoreConfigInvalid(#[from] OscoreConfigError),
128}
129
130#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
131pub enum UnknownOptionError {
132    /// Unknown error inside of libcoap
133    #[error("CoAP option conversion error: unknown option")]
134    Unknown,
135}
136
137#[derive(Error, Debug)]
138pub enum RngError {
139    /// Unknown error inside of libcoap
140    #[error("CoAP RNG error: unknown error in call to libcoap")]
141    Unknown,
142    /// RNG mutex is poisoned (panic in another thread while calling RNG function).
143    #[error("CoAP RNG configuration error: global RNG mutex is poisoned")]
144    GlobalMutexPoisonError,
145}
146
147impl<T> From<PoisonError<T>> for RngError {
148    fn from(_value: PoisonError<T>) -> Self {
149        RngError::GlobalMutexPoisonError
150    }
151}
152
153#[derive(Error, Debug, Clone, Eq, PartialEq)]
154pub enum OptionValueError {
155    /// Provided value for option is too short.
156    #[error("CoAP option has invalid value: too short")]
157    TooShort,
158    /// Provided value for option is too long.
159    #[error("CoAP option has invalid value: too long")]
160    TooLong,
161    /// A string value could not be converted to UTF-8.
162    #[error("CoAP option has invalid value: invalid string")]
163    StringConversion(#[from] FromUtf8Error),
164    /// URI encoded in message could not be parsed.
165    #[error("CoAP option has invalid value: invalid URI")]
166    UriParsing(#[from] UriParsingError),
167    /// Option has an illegal value.
168    #[error("CoAP option has invalid value")]
169    IllegalValue,
170}
171
172#[derive(Error, Debug, Clone, Eq, PartialEq)]
173pub enum UriParsingError {
174    /// Unknown error inside of libcoap
175    #[error("CoAP option creation error: unknown error in call to libcoap")]
176    Unknown,
177    /// URI does not have a valid scheme for libcoap (coap, coaps, coap+tcp, coaps+tcp, http, https).
178    #[error("URI scheme {} is not a valid CoAP scheme known to libcoap", .0)]
179    NotACoapScheme(String),
180    /// Provided URI contains a null byte.
181    #[error("Provided URI contains a null byte")]
182    ContainsNullByte(#[from] NulError),
183}
184
185#[derive(Error, Debug, Clone, Eq, PartialEq)]
186pub enum MessageConversionError {
187    /// Value of an option is invalid.
188    #[error("CoAP message conversion error: invalid option value for {:?}", .0)]
189    InvalidOptionValue(Option<CoapOptionType>, #[source] OptionValueError),
190    /// Message has an option that is specific for another message type (i.e., request option in
191    /// response message).
192    #[error("CoAP message conversion error: option of type {:?} invalid for message type", .0)]
193    InvalidOptionForMessageType(CoapOptionType),
194    /// Non-repeatable option was repeated.
195    #[error("CoAP message conversion error: non-repeatable option of type {:?} repeated", .0)]
196    NonRepeatableOptionRepeated(CoapOptionType),
197    /// Provided URI has invalid scheme.
198    #[error("CoAP message conversion error: provided uri does not have scheme valid for CoAP")]
199    NotACoapUri(UriParsingError),
200    /// Invalid message code.
201    #[error("CoAP message conversion error: invalid message code")]
202    InvalidMessageCode(#[from] MessageCodeError),
203    /// A message with code 0.00 (Empty) contains data.
204    #[error("CoAP message conversion error: empty message contains data")]
205    DataInEmptyMessage,
206    /// Message has no token.
207    #[error("CoAP message conversion error: token missing")]
208    MissingToken,
209    /// Message has no ID.
210    #[error("CoAP message conversion error: message id missing")]
211    MissingMessageId,
212    /// Two (or more) options were combined which must not be combined (e.g., Proxy-Scheme and
213    /// Proxy-URI).
214    #[error("CoAP message conversion error: options {:?} and {:?} cannot be combined", .0, .1)]
215    InvalidOptionCombination(CoapOptionType, CoapOptionType),
216    /// A critical option (as defined in [RFC 7252](https://datatracker.ietf.org/doc/html/rfc7252#section-5.4.1)
217    /// was not recognized).
218    #[error("CoAP option identified as critical but not recognized")]
219    CriticalOptionUnrecognized,
220    /// Unknown error inside of libcoap.
221    #[error("unknown CoAP message conversion error")]
222    Unknown,
223}
224
225impl From<UriParsingError> for MessageConversionError {
226    fn from(v: UriParsingError) -> Self {
227        MessageConversionError::NotACoapUri(v)
228    }
229}
230
231#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
232pub enum MessageCodeError {
233    /// Provided message code for request was not a request code.
234    #[error("CoAP message code conversion error: not a request code")]
235    NotARequestCode,
236    /// Provided message code for response was not a response code.
237    #[error("CoAP message code conversion error: not a response code")]
238    NotAResponseCode,
239}
240
241#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
242pub enum MessageTypeError {
243    /// Message type cannot be used for this message code (e.g., ACK for request).
244    #[error("message type {:?} cannot be used for this message code", .0)]
245    InvalidForMessageCode(CoapMessageType),
246}