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#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
41pub enum ContextConfigurationError {
42    /// Unknown error inside of libcoap
43    #[error("CoAP context configuration error: unknown error in call to libcoap")]
44    Unknown,
45    #[error(
46        "CoAP context configuration error: attempted to set encryption context while one has already been configured for this encryption variant"
47    )]
48    CryptoContextAlreadySet,
49}
50
51#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
52pub enum MessageCreationError {
53    /// Unknown error inside of libcoap
54    #[error("CoAP message creation error: unknown error in call to libcoap")]
55    Unknown,
56}
57
58#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
59pub enum IoProcessError {
60    /// Unknown error inside of libcoap
61    #[error("CoAP IO error: unknown error in call to libcoap")]
62    Unknown,
63}
64
65#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
66pub enum SessionGetAppDataError {
67    /// Stored application data type differs from requested type
68    #[error("CoAP application data retrieval error: wrong type")]
69    WrongType,
70}
71
72#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
73pub enum OptionCreationError {
74    /// Unknown error inside of libcoap
75    #[error("CoAP option creation error: unknown error in call to libcoap")]
76    Unknown,
77}
78
79#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
80pub enum SessionCreationError {
81    /// Unknown error inside of libcoap
82    #[error("CoAP session creation error: unknown error in call to libcoap")]
83    Unknown,
84}
85
86#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
87pub enum UnknownOptionError {
88    /// Unknown error inside of libcoap
89    #[error("CoAP option conversion error: unknown option")]
90    Unknown,
91}
92
93#[derive(Error, Debug)]
94pub enum RngError {
95    /// Unknown error inside of libcoap
96    #[error("CoAP RNG error: unknown error in call to libcoap")]
97    Unknown,
98    /// RNG mutex is poisoned (panic in another thread while calling RNG function).
99    #[error("CoAP RNG configuration error: global RNG mutex is poisoned")]
100    GlobalMutexPoisonError,
101}
102
103impl<T> From<PoisonError<T>> for RngError {
104    fn from(_value: PoisonError<T>) -> Self {
105        RngError::GlobalMutexPoisonError
106    }
107}
108
109#[derive(Error, Debug, Clone, Eq, PartialEq)]
110pub enum OptionValueError {
111    /// Provided value for option is too short.
112    #[error("CoAP option has invalid value: too short")]
113    TooShort,
114    /// Provided value for option is too long.
115    #[error("CoAP option has invalid value: too long")]
116    TooLong,
117    /// A string value could not be converted to UTF-8.
118    #[error("CoAP option has invalid value: invalid string")]
119    StringConversion(#[from] FromUtf8Error),
120    /// URI encoded in message could not be parsed.
121    #[error("CoAP option has invalid value: invalid URI")]
122    UriParsing(#[from] UriParsingError),
123    /// Option has an illegal value.
124    #[error("CoAP option has invalid value")]
125    IllegalValue,
126}
127
128#[derive(Error, Debug, Clone, Eq, PartialEq)]
129pub enum UriParsingError {
130    /// Unknown error inside of libcoap
131    #[error("CoAP option creation error: unknown error in call to libcoap")]
132    Unknown,
133    /// URI does not have a valid scheme for libcoap (coap, coaps, coap+tcp, coaps+tcp, http, https).
134    #[error("URI scheme {} is not a valid CoAP scheme known to libcoap", .0)]
135    NotACoapScheme(String),
136    /// Provided URI contains a null byte.
137    #[error("Provided URI contains a null byte")]
138    ContainsNullByte(#[from] NulError),
139}
140
141#[derive(Error, Debug, Clone, Eq, PartialEq)]
142pub enum MessageConversionError {
143    /// Value of an option is invalid.
144    #[error("CoAP message conversion error: invalid option value for {:?}", .0)]
145    InvalidOptionValue(Option<CoapOptionType>, #[source] OptionValueError),
146    /// Message has an option that is specific for another message type (i.e., request option in
147    /// response message).
148    #[error("CoAP message conversion error: option of type {:?} invalid for message type", .0)]
149    InvalidOptionForMessageType(CoapOptionType),
150    /// Non-repeatable option was repeated.
151    #[error("CoAP message conversion error: non-repeatable option of type {:?} repeated", .0)]
152    NonRepeatableOptionRepeated(CoapOptionType),
153    /// Provided URI has invalid scheme.
154    #[error("CoAP message conversion error: provided uri does not have scheme valid for CoAP")]
155    NotACoapUri(UriParsingError),
156    /// Invalid message code.
157    #[error("CoAP message conversion error: invalid message code")]
158    InvalidMessageCode(#[from] MessageCodeError),
159    /// A message with code 0.00 (Empty) contains data.
160    #[error("CoAP message conversion error: empty message contains data")]
161    DataInEmptyMessage,
162    /// Message has no token.
163    #[error("CoAP message conversion error: token missing")]
164    MissingToken,
165    /// Message has no ID.
166    #[error("CoAP message conversion error: message id missing")]
167    MissingMessageId,
168    /// Two (or more) options were combined which must not be combined (e.g., Proxy-Scheme and
169    /// Proxy-URI).
170    #[error("CoAP message conversion error: options {:?} and {:?} cannot be combined", .0, .1)]
171    InvalidOptionCombination(CoapOptionType, CoapOptionType),
172    /// A critical option (as defined in [RFC 7252](https://datatracker.ietf.org/doc/html/rfc7252#section-5.4.1)
173    /// was not recognized).
174    #[error("CoAP option identified as critical but not recognized")]
175    CriticalOptionUnrecognized,
176    /// Unknown error inside of libcoap.
177    #[error("unknown CoAP message conversion error")]
178    Unknown,
179}
180
181impl From<UriParsingError> for MessageConversionError {
182    fn from(v: UriParsingError) -> Self {
183        MessageConversionError::NotACoapUri(v)
184    }
185}
186
187#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
188pub enum MessageCodeError {
189    /// Provided message code for request was not a request code.
190    #[error("CoAP message code conversion error: not a request code")]
191    NotARequestCode,
192    /// Provided message code for response was not a response code.
193    #[error("CoAP message code conversion error: not a response code")]
194    NotAResponseCode,
195}
196
197#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
198pub enum MessageTypeError {
199    /// Message type cannot be used for this message code (e.g., ACK for request).
200    #[error("message type {:?} cannot be used for this message code", .0)]
201    InvalidForMessageCode(CoapMessageType),
202}