1use reqwest::{Response, StatusCode};
5use thiserror::Error;
6
7#[derive(Error, Debug)]
9pub enum IntelApiError {
10 #[error("Unsupported API version or feature: {0}")]
12 UnsupportedApiVersion(String),
13
14 #[error("Reqwest error: {0}")]
16 Reqwest(#[from] reqwest::Error),
17
18 #[error("URL parsing error: {0}")]
20 UrlParse(#[from] url::ParseError),
21
22 #[error("Serde JSON error: {0}")]
24 JsonError(#[from] serde_json::Error),
25
26 #[error("API Error: Status={status}, Request-ID={request_id}, Code={error_code:?}, Message={error_message:?}")]
28 ApiError {
29 status: StatusCode,
31 request_id: String,
33 error_code: Option<String>,
35 error_message: Option<String>,
37 },
38
39 #[error("Header missing or invalid: {0}")]
41 MissingOrInvalidHeader(&'static str),
42
43 #[error("Invalid Subscription Key format")]
45 InvalidSubscriptionKey,
46
47 #[error("Cannot provide conflicting parameters: {0}")]
49 ConflictingParameters(&'static str),
50
51 #[error("I/O Error: {0}")]
53 Io(#[from] std::io::Error),
54
55 #[error("Header value parse error for '{0}': {1}")]
57 HeaderValueParse(&'static str, String),
58
59 #[error("Invalid parameter value: {0}")]
61 InvalidParameter(&'static str),
62}
63
64pub(crate) fn extract_api_error_details(
66 response: &Response,
67) -> (String, Option<String>, Option<String>) {
68 let request_id = response
69 .headers()
70 .get("Request-ID")
71 .and_then(|v| v.to_str().ok())
72 .unwrap_or("Unknown")
73 .to_string();
74 let error_code = response
75 .headers()
76 .get("Error-Code")
77 .and_then(|v| v.to_str().ok())
78 .map(String::from);
79 let error_message = response
80 .headers()
81 .get("Error-Message")
82 .and_then(|v| v.to_str().ok())
83 .map(String::from);
84 (request_id, error_code, error_message)
85}
86
87pub(crate) async fn check_status(
89 response: Response,
90 expected_statuses: &[StatusCode],
91) -> Result<Response, IntelApiError> {
92 let status = response.status();
93 if expected_statuses.contains(&status) {
94 Ok(response)
95 } else {
96 let (request_id, error_code, error_message) = extract_api_error_details(&response);
97 Err(IntelApiError::ApiError {
98 status,
99 request_id,
100 error_code,
101 error_message,
102 })
103 }
104}