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

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

            
15
use thiserror::Error;
16

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

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

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

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

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

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

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

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

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

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

            
89
impl<T> From<PoisonError<T>> for RngError {
90
    fn from(_value: PoisonError<T>) -> Self {
91
        RngError::GlobalMutexPoisonError
92
    }
93
}
94

            
95
#[derive(Error, Debug, Clone, Eq, PartialEq)]
96
pub enum OptionValueError {
97
    /// Provided value for option is too short.
98
    #[error("CoAP option has invalid value: too short")]
99
    TooShort,
100
    /// Provided value for option is too long.
101
    #[error("CoAP option has invalid value: too long")]
102
    TooLong,
103
    /// A string value could not be converted to UTF-8.
104
    #[error("CoAP option has invalid value: invalid string")]
105
    StringConversion(#[from] FromUtf8Error),
106
    /// URI encoded in message could not be parsed.
107
    #[error("CoAP option has invalid value: invalid URI")]
108
    UriParsing(#[from] UriParsingError),
109
    /// Option has an illegal value.
110
    #[error("CoAP option has invalid value")]
111
    IllegalValue,
112
}
113

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

            
127
#[derive(Error, Debug, Clone, Eq, PartialEq)]
128
pub enum MessageConversionError {
129
    /// Value of an option is invalid.
130
    #[error("CoAP message conversion error: invalid option value for {:?}", .0)]
131
    InvalidOptionValue(Option<CoapOptionType>, #[source] OptionValueError),
132
    /// Message has an option that is specific for another message type (i.e., request option in
133
    /// response message).
134
    #[error("CoAP message conversion error: option of type {:?} invalid for message type", .0)]
135
    InvalidOptionForMessageType(CoapOptionType),
136
    /// Non-repeatable option was repeated.
137
    #[error("CoAP message conversion error: non-repeatable option of type {:?} repeated", .0)]
138
    NonRepeatableOptionRepeated(CoapOptionType),
139
    /// Provided URI has invalid scheme.
140
    #[error("CoAP message conversion error: provided uri does not have scheme valid for CoAP")]
141
    NotACoapUri(UriParsingError),
142
    /// Invalid message code.
143
    #[error("CoAP message conversion error: invalid message code")]
144
    InvalidMessageCode(#[from] MessageCodeError),
145
    /// A message with code 0.00 (Empty) contains data.
146
    #[error("CoAP message conversion error: empty message contains data")]
147
    DataInEmptyMessage,
148
    /// Message has no token.
149
    #[error("CoAP message conversion error: token missing")]
150
    MissingToken,
151
    /// Message has no ID.
152
    #[error("CoAP message conversion error: message id missing")]
153
    MissingMessageId,
154
    /// Two (or more) options were combined which must not be combined (e.g., Proxy-Scheme and
155
    /// Proxy-URI).
156
    #[error("CoAP message conversion error: options {:?} and {:?} cannot be combined", .0, .1)]
157
    InvalidOptionCombination(CoapOptionType, CoapOptionType),
158
    /// A critical option (as defined in [RFC 7252](https://datatracker.ietf.org/doc/html/rfc7252#section-5.4.1)
159
    /// was not recognized).
160
    #[error("CoAP option identified as critical but not recognized")]
161
    CriticalOptionUnrecognized,
162
    /// Unknown error inside of libcoap.
163
    #[error("unknown CoAP message conversion error")]
164
    Unknown,
165
}
166

            
167
impl From<UriParsingError> for MessageConversionError {
168
    fn from(v: UriParsingError) -> Self {
169
        MessageConversionError::NotACoapUri(v)
170
    }
171
}
172

            
173
#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
174
pub enum MessageCodeError {
175
    /// Provided message code for request was not a request code.
176
    #[error("CoAP message code conversion error: not a request code")]
177
    NotARequestCode,
178
    /// Provided message code for response was not a response code.
179
    #[error("CoAP message code conversion error: not a response code")]
180
    NotAResponseCode,
181
}
182

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