libcoap_rs/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright © The libcoap-rs Contributors, all rights reserved.
 * This file is part of the libcoap-rs project, see the README file for
 * general information on this project and the NOTICE.md and LICENSE files
 * for information regarding copyright ownership and terms of use.
 *
 * error.rs - CoAP error types.
 */

//! Error types

use std::{ffi::NulError, string::FromUtf8Error, sync::PoisonError};

use thiserror::Error;

use crate::protocol::{CoapMessageType, CoapOptionType};

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum EndpointCreationError {
    /// Unknown error inside of libcoap
    #[error("CoAP endpoint creation error: unknown error in call to libcoap")]
    Unknown,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum ContextConfigurationError {
    /// Unknown error inside of libcoap
    #[error("CoAP context configuration error: unknown error in call to libcoap")]
    Unknown,
    #[error(
        "CoAP context configuration error: attempted to set encryption context while one has already been configured for this encryption variant"
    )]
    CryptoContextAlreadySet,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum MessageCreationError {
    /// Unknown error inside of libcoap
    #[error("CoAP message creation error: unknown error in call to libcoap")]
    Unknown,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum IoProcessError {
    /// Unknown error inside of libcoap
    #[error("CoAP IO error: unknown error in call to libcoap")]
    Unknown,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum SessionGetAppDataError {
    /// Stored application data type differs from requested type
    #[error("CoAP application data retrieval error: wrong type")]
    WrongType,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum OptionCreationError {
    /// Unknown error inside of libcoap
    #[error("CoAP option creation error: unknown error in call to libcoap")]
    Unknown,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum SessionCreationError {
    /// Unknown error inside of libcoap
    #[error("CoAP session creation error: unknown error in call to libcoap")]
    Unknown,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum UnknownOptionError {
    /// Unknown error inside of libcoap
    #[error("CoAP option conversion error: unknown option")]
    Unknown,
}

#[derive(Error, Debug)]
pub enum RngError {
    /// Unknown error inside of libcoap
    #[error("CoAP RNG error: unknown error in call to libcoap")]
    Unknown,
    /// RNG mutex is poisoned (panic in another thread while calling RNG function).
    #[error("CoAP RNG configuration error: global RNG mutex is poisoned")]
    GlobalMutexPoisonError,
}

impl<T> From<PoisonError<T>> for RngError {
    fn from(_value: PoisonError<T>) -> Self {
        RngError::GlobalMutexPoisonError
    }
}

#[derive(Error, Debug, Clone, Eq, PartialEq)]
pub enum OptionValueError {
    /// Provided value for option is too short.
    #[error("CoAP option has invalid value: too short")]
    TooShort,
    /// Provided value for option is too long.
    #[error("CoAP option has invalid value: too long")]
    TooLong,
    /// A string value could not be converted to UTF-8.
    #[error("CoAP option has invalid value: invalid string")]
    StringConversion(#[from] FromUtf8Error),
    /// URI encoded in message could not be parsed.
    #[error("CoAP option has invalid value: invalid URI")]
    UriParsing(#[from] UriParsingError),
    /// Option has an illegal value.
    #[error("CoAP option has invalid value")]
    IllegalValue,
}

#[derive(Error, Debug, Clone, Eq, PartialEq)]
pub enum UriParsingError {
    /// Unknown error inside of libcoap
    #[error("CoAP option creation error: unknown error in call to libcoap")]
    Unknown,
    /// URI does not have a valid scheme for libcoap (coap, coaps, coap+tcp, coaps+tcp, http, https).
    #[error("URI scheme {} is not a valid CoAP scheme known to libcoap", .0)]
    NotACoapScheme(String),
    /// Provided URI contains a null byte.
    #[error("Provided URI contains a null byte")]
    ContainsNullByte(#[from] NulError),
}

#[derive(Error, Debug, Clone, Eq, PartialEq)]
pub enum MessageConversionError {
    /// Value of an option is invalid.
    #[error("CoAP message conversion error: invalid option value for {:?}", .0)]
    InvalidOptionValue(Option<CoapOptionType>, #[source] OptionValueError),
    /// Message has an option that is specific for another message type (i.e., request option in
    /// response message).
    #[error("CoAP message conversion error: option of type {:?} invalid for message type", .0)]
    InvalidOptionForMessageType(CoapOptionType),
    /// Non-repeatable option was repeated.
    #[error("CoAP message conversion error: non-repeatable option of type {:?} repeated", .0)]
    NonRepeatableOptionRepeated(CoapOptionType),
    /// Provided URI has invalid scheme.
    #[error("CoAP message conversion error: provided uri does not have scheme valid for CoAP")]
    NotACoapUri(UriParsingError),
    /// Invalid message code.
    #[error("CoAP message conversion error: invalid message code")]
    InvalidMessageCode(#[from] MessageCodeError),
    /// A message with code 0.00 (Empty) contains data.
    #[error("CoAP message conversion error: empty message contains data")]
    DataInEmptyMessage,
    /// Message has no token.
    #[error("CoAP message conversion error: token missing")]
    MissingToken,
    /// Message has no ID.
    #[error("CoAP message conversion error: message id missing")]
    MissingMessageId,
    /// Two (or more) options were combined which must not be combined (e.g., Proxy-Scheme and
    /// Proxy-URI).
    #[error("CoAP message conversion error: options {:?} and {:?} cannot be combined", .0, .1)]
    InvalidOptionCombination(CoapOptionType, CoapOptionType),
    /// A critical option (as defined in [RFC 7252](https://datatracker.ietf.org/doc/html/rfc7252#section-5.4.1)
    /// was not recognized).
    #[error("CoAP option identified as critical but not recognized")]
    CriticalOptionUnrecognized,
    /// Unknown error inside of libcoap.
    #[error("unknown CoAP message conversion error")]
    Unknown,
}

impl From<UriParsingError> for MessageConversionError {
    fn from(v: UriParsingError) -> Self {
        MessageConversionError::NotACoapUri(v)
    }
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum MessageCodeError {
    /// Provided message code for request was not a request code.
    #[error("CoAP message code conversion error: not a request code")]
    NotARequestCode,
    /// Provided message code for response was not a response code.
    #[error("CoAP message code conversion error: not a response code")]
    NotAResponseCode,
}

#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
pub enum MessageTypeError {
    /// Message type cannot be used for this message code (e.g., ACK for request).
    #[error("message type {:?} cannot be used for this message code", .0)]
    InvalidForMessageCode(CoapMessageType),
}