blob_indexer/clients/
macros.rs

1#[macro_export]
2/// Make a GET request sending and expecting JSON.
3/// if JSON deser fails, emit a `WARN` level tracing event
4macro_rules! json_get {
5    ($client:expr, $url:expr, $expected:ty, $exp_backoff:expr) => {
6        json_get!($client, $url, $expected, "", $exp_backoff)
7    };
8    ($client:expr, $url:expr, $expected:ty, $auth_token:expr, $exp_backoff: expr) => {{
9        let url = $url.clone();
10
11        tracing::trace!(method = "GET", url = url.as_str(), "Dispatching API request");
12
13        let mut req = $client.get($url);
14
15        if !$auth_token.is_empty() {
16          req = req.bearer_auth($auth_token);
17        }
18
19        let resp = if $exp_backoff.is_some() {
20            match backoff::future::retry_notify(
21                $exp_backoff.unwrap(),
22                || {
23                    let req = req.try_clone().unwrap();
24
25                    async move { req.send().await.map_err(|err| err.into()) }
26                },
27                |error, duration: std::time::Duration| {
28                    let duration = duration.as_secs();
29
30                    tracing::warn!(
31                        method = "GET",
32                        url = %url,
33                        ?error,
34                        "Failed to send request. Retrying in {duration} seconds…"
35                    );
36                },
37            )
38            .await {
39                Ok(resp) => resp,
40                Err(error) => {
41                    tracing::warn!(
42                        method = "GET",
43                        url = %url,
44                        ?error,
45                        "Failed to send request. All retries failed"
46                    );
47
48                    return Err(error.into())
49                }
50            }
51        } else {
52            match req.send().await {
53                Err(error) => {
54                    tracing::warn!(
55                        method = "GET",
56                        url = %url,
57                        ?error,
58                        "Failed to send request"
59                    );
60
61                    return Err(error.into())
62                },
63                Ok(resp) => resp
64            }
65        };
66
67        let status = resp.status();
68
69        if status.as_u16() == 404 {
70          return Ok(None)
71        };
72
73        let text = resp.text().await?;
74        let result: Result<$crate::clients::common::ClientResponse<$expected>, _> = serde_json::from_str(&text);
75
76        match result {
77            Err(e) => {
78                tracing::warn!(
79                    method = "GET",
80                    url = %url,
81                    response = text.as_str(),
82                    "Unexpected response from server"
83                );
84
85                Err(e.into())
86            },
87            Ok(response) => {
88              response.into_client_result()
89            }
90        }
91    }};
92}
93
94#[macro_export]
95/// Make a PUT request sending JSON.
96/// if JSON deser fails, emit a `WARN` level tracing event
97macro_rules! json_put {
98    ($client:expr, $url:expr, $auth_token:expr, $body:expr) => {
99        json_put!($client, $url, (), $auth_token, $body)
100    };
101    ($client:expr, $url:expr, $expected:ty, $auth_token:expr, $body:expr) => {{
102        let url = $url.clone();
103        let body = format!("{:?}", $body);
104
105        tracing::trace!(method = "PUT", url = url.as_str(), body, "Dispatching API client request");
106
107
108        let resp = match $client
109            .put($url)
110            .bearer_auth($auth_token)
111            .json($body)
112            .send()
113            .await {
114                Err(error) => {
115                    tracing::warn!(
116                        method = "PUT",
117                        url = %url,
118                        body = body,
119                        ?error,
120                        "Failed to send request"
121                    );
122
123                    return Err(error.into())
124                },
125                Ok(resp) => resp
126            };
127
128        let text = resp.text().await?;
129        let result: $crate::clients::common::ClientResponse<$expected> = text.parse()?;
130
131        if result.is_err() {
132            tracing::warn!(
133                method = "PUT",
134                url = %url,
135                body,
136                response = text.as_str(),
137                "Unexpected response from server"
138            );
139        }
140
141        result.into_client_result()
142    }};
143}