opendev_http/models/
mod.rs1mod retry;
4
5pub use retry::{RetryConfig, classify_retryable_error, parse_retry_after};
6
7#[derive(Debug, thiserror::Error)]
9pub enum HttpError {
10 #[error("HTTP request failed: {0}")]
11 Request(#[from] reqwest::Error),
12
13 #[error("Interrupted by user")]
14 Interrupted,
15
16 #[error("All retries exhausted: {message}")]
17 RetriesExhausted { message: String },
18
19 #[error("Authentication error: {0}")]
20 Auth(String),
21
22 #[error("IO error: {0}")]
23 Io(#[from] std::io::Error),
24
25 #[error("JSON error: {0}")]
26 Json(#[from] serde_json::Error),
27
28 #[error("{0}")]
29 Other(String),
30}
31
32#[derive(Debug)]
34pub struct HttpResult {
35 pub success: bool,
37 pub status: Option<u16>,
39 pub body: Option<serde_json::Value>,
41 pub error: Option<String>,
43 pub interrupted: bool,
45 pub retryable: bool,
47 pub request_id: Option<String>,
50 pub retry_after: Option<String>,
53 pub retry_after_ms: Option<String>,
56}
57
58impl HttpResult {
59 pub fn ok(status: u16, body: serde_json::Value) -> Self {
61 Self {
62 success: true,
63 status: Some(status),
64 body: Some(body),
65 error: None,
66 interrupted: false,
67 retryable: false,
68 request_id: None,
69 retry_after: None,
70 retry_after_ms: None,
71 }
72 }
73
74 pub fn fail(error: impl Into<String>, retryable: bool) -> Self {
76 Self {
77 success: false,
78 status: None,
79 body: None,
80 error: Some(error.into()),
81 interrupted: false,
82 retryable,
83 request_id: None,
84 retry_after: None,
85 retry_after_ms: None,
86 }
87 }
88
89 pub fn interrupted() -> Self {
91 Self {
92 success: false,
93 status: None,
94 body: None,
95 error: Some("Interrupted by user".into()),
96 interrupted: true,
97 retryable: false,
98 request_id: None,
99 retry_after: None,
100 retry_after_ms: None,
101 }
102 }
103
104 pub fn retryable_status(
106 status: u16,
107 body: Option<serde_json::Value>,
108 retry_after: Option<String>,
109 ) -> Self {
110 Self {
111 success: false,
112 status: Some(status),
113 body,
114 error: Some(format!("HTTP {status}")),
115 interrupted: false,
116 retryable: true,
117 request_id: None,
118 retry_after,
119 retry_after_ms: None,
120 }
121 }
122
123 pub fn with_request_id(mut self, request_id: impl Into<String>) -> Self {
125 self.request_id = Some(request_id.into());
126 self
127 }
128}
129
130#[cfg(test)]
131mod tests;