Skip to main content

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    /// Attempted to set CoapRng as RNG provided to libcoap.
146    #[error("CoAP RNG configuration error: attempted to provide libcoap's own RNG wrapper to itself")]
147    CoapRngAsCustomRng,
148}
149
150impl<T> From<PoisonError<T>> for RngError {
151    fn from(_value: PoisonError<T>) -> Self {
152        RngError::GlobalMutexPoisonError
153    }
154}
155
156#[derive(Error, Debug, Clone, Eq, PartialEq)]
157pub enum OptionValueError {
158    /// Provided value for option is too short.
159    #[error("CoAP option has invalid value: too short")]
160    TooShort,
161    /// Provided value for option is too long.
162    #[error("CoAP option has invalid value: too long")]
163    TooLong,
164    /// A string value could not be converted to UTF-8.
165    #[error("CoAP option has invalid value: invalid string")]
166    StringConversion(#[from] FromUtf8Error),
167    /// URI encoded in message could not be parsed.
168    #[error("CoAP option has invalid value: invalid URI")]
169    UriParsing(#[from] UriParsingError),
170    /// Option has an illegal value.
171    #[error("CoAP option has invalid value")]
172    IllegalValue,
173}
174
175#[derive(Error, Debug, Clone, Eq, PartialEq)]
176pub enum UriParsingError {
177    /// Unknown error inside of libcoap
178    #[error("CoAP option creation error: unknown error in call to libcoap")]
179    Unknown,
180    /// URI does not have a valid scheme for libcoap (coap, coaps, coap+tcp, coaps+tcp, http, https).
181    #[error("URI scheme {} is not a valid CoAP scheme known to libcoap", .0)]
182    NotACoapScheme(String),
183    /// Provided URI contains a null byte.
184    #[error("Provided URI contains a null byte")]
185    ContainsNullByte(#[from] NulError),
186}
187
188#[derive(Error, Debug, Clone, Eq, PartialEq)]
189pub enum MessageConversionError {
190    /// Value of an option is invalid.
191    #[error("CoAP message conversion error: invalid option value for {:?}", .0)]
192    InvalidOptionValue(Option<CoapOptionType>, #[source] OptionValueError),
193    /// Message has an option that is specific for another message type (i.e., request option in
194    /// response message).
195    #[error("CoAP message conversion error: option of type {:?} invalid for message type", .0)]
196    InvalidOptionForMessageType(CoapOptionType),
197    /// Non-repeatable option was repeated.
198    #[error("CoAP message conversion error: non-repeatable option of type {:?} repeated", .0)]
199    NonRepeatableOptionRepeated(CoapOptionType),
200    /// Provided URI has invalid scheme.
201    #[error("CoAP message conversion error: provided uri does not have scheme valid for CoAP")]
202    NotACoapUri(UriParsingError),
203    /// Invalid message code.
204    #[error("CoAP message conversion error: invalid message code")]
205    InvalidMessageCode(#[from] MessageCodeError),
206    /// A message with code 0.00 (Empty) contains data.
207    #[error("CoAP message conversion error: empty message contains data")]
208    DataInEmptyMessage,
209    /// Message has no token.
210    #[error("CoAP message conversion error: token missing")]
211    MissingToken,
212    /// Message has no ID.
213    #[error("CoAP message conversion error: message id missing")]
214    MissingMessageId,
215    /// Two (or more) options were combined which must not be combined (e.g., Proxy-Scheme and
216    /// Proxy-URI).
217    #[error("CoAP message conversion error: options {:?} and {:?} cannot be combined", .0, .1)]
218    InvalidOptionCombination(CoapOptionType, CoapOptionType),
219    /// A critical option (as defined in [RFC 7252](https://datatracker.ietf.org/doc/html/rfc7252#section-5.4.1)
220    /// was not recognized).
221    #[error("CoAP option identified as critical but not recognized")]
222    CriticalOptionUnrecognized,
223    /// Unknown error inside of libcoap.
224    #[error("unknown CoAP message conversion error")]
225    Unknown,
226}
227
228impl From<UriParsingError> for MessageConversionError {
229    fn from(v: UriParsingError) -> Self {
230        MessageConversionError::NotACoapUri(v)
231    }
232}
233
234#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
235pub enum MessageCodeError {
236    /// Provided message code for request was not a request code.
237    #[error("CoAP message code conversion error: not a request code")]
238    NotARequestCode,
239    /// Provided message code for response was not a response code.
240    #[error("CoAP message code conversion error: not a response code")]
241    NotAResponseCode,
242}
243
244#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
245pub enum MessageTypeError {
246    /// Message type cannot be used for this message code (e.g., ACK for request).
247    #[error("message type {:?} cannot be used for this message code", .0)]
248    InvalidForMessageCode(CoapMessageType),
249}