fundamentum_edge_mcu_http_client/http_client_error.rs
1use core::num::ParseIntError;
2
3use displaydoc::Display;
4use serde_json_core::de;
5use thiserror_no_std::Error;
6
7use crate::{http_handler::HttpHandler, models::StatusCode};
8
9/// Errors that might get returned by the [`HttpClient`](crate::HttpClient).
10//
11// TODO: ASP00009-1807: The error types of the HttpClient might not rely on the HttpHandler directly
12#[derive(Error, Display)]
13#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
14#[cfg_attr(feature = "log", derive(defmt::Format))]
15pub enum HttpClientError<H: HttpHandler> {
16 /// Cannot serialize the body because the buffer is full: {0}
17 SerializationBufferFull(usize),
18 /// Cannot serialize the body
19 Serialization,
20 /// Cannot convert UTF-8 characters: Valid up to {0}
21 Utf8Conversion(usize),
22 /// Failed to send HTTPS request
23 SendRequest(H::Error),
24 /// No status code found in the HTTP response
25 NoStatusCode,
26 /// Cannot parse the HTTP response: {0:?}
27 #[cfg(feature = "log")]
28 ParseHttp(#[defmt(Debug2Format)] httparse::Error),
29 /// Cannot parse the HTTP response
30 #[cfg(not(feature = "log"))]
31 ParseHttp(httparse::Error),
32 /// The HTTPS response is only partial
33 PartialHttpRequest,
34 /// No content header in response
35 NoContentHeader,
36 /// Cannot convert &[u8] buffer into a 'usize': {0:?}
37 #[cfg(feature = "log")]
38 ContentLengthConversion(#[defmt(Debug2Format)] ParseIntError),
39 #[cfg(not(feature = "log"))]
40 /// Cannot convert &[u8] buffer into a 'usize'
41 ContentLengthConversion(ParseIntError),
42 /// Cannot deserialize the body into the provided type {0:?}
43 #[cfg(feature = "log")]
44 DeserializationFailed(#[defmt(Debug2Format)] de::Error),
45 /// Cannot deserialize the body into the provided type
46 #[cfg(not(feature = "log"))]
47 DeserializationFailed(de::Error),
48 /// Request Might have failed: no "status" field found
49 MissingStatusField,
50 /// Request succeeded but no "data" field found
51 MissingDataField,
52 /// Request failed and no "message" field found
53 FailedAndMissingMessageField,
54 /// Error coming from the Api with message (message stored in [`HttpClientErrorWrapper`])
55 GenericApiError(StatusCode),
56}
57
58/// Errors with the error message returned by [`HttpClient`](crate::HttpClient).
59///
60/// ### Note
61///
62/// This enum is created because there cannot be a lifetime on [`HttpClientError`]
63/// ; the client must be able to handle the error in `start()`, which cannot
64/// be achieved with the lifetime bounded to a buffer in `main()`.
65#[derive(Error, Display)]
66#[cfg_attr(test, derive(Debug, PartialEq))]
67#[cfg_attr(feature = "log", derive(defmt::Format))]
68pub enum HttpClientErrorWrapper<'a, H: HttpHandler> {
69 /// Other errors from [`HttpClientError`].
70 OtherErrors(#[from] HttpClientError<H>),
71 /// Error coming from the API with message.
72 GenericApiError {
73 /// Error message from the Fundamentum API.
74 message: &'a str,
75 /// Status code received.
76 status_code: StatusCode,
77 },
78}
79
80impl<H: HttpHandler> From<HttpClientErrorWrapper<'_, H>> for HttpClientError<H> {
81 fn from(err: HttpClientErrorWrapper<H>) -> Self {
82 match err {
83 HttpClientErrorWrapper::OtherErrors(e) => e,
84 HttpClientErrorWrapper::GenericApiError { status_code, .. } => {
85 Self::GenericApiError(status_code)
86 }
87 }
88 }
89}