MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / handle_response

Method handle_response

atomic-remote/src/storage.rs:210–246  ·  view source on GitHub ↗

Handle a response: check status, parse `ApiResponse `, unwrap data.

(
        &self,
        resp: reqwest::Response,
    )

Source from the content-addressed store, hash-verified

208
209 /// Handle a response: check status, parse `ApiResponse<T>`, unwrap data.
210 async fn handle_response<T: DeserializeOwned>(
211 &self,
212 resp: reqwest::Response,
213 ) -> Result<T, RemoteError> {
214 crate::check_min_version_header(resp.headers());
215 let status = resp.status();
216 let body = resp
217 .text()
218 .await
219 .map_err(|e| RemoteError::other(format!("failed to read response: {}", e)))?;
220
221 if !status.is_success() {
222 return Err(self.parse_error_body(status.as_u16(), &body));
223 }
224
225 let api_resp: ApiResponse<T> = serde_json::from_str(&body).map_err(|e| {
226 // The whole body goes to the log; the error message carries a
227 // bounded preview so a large payload cannot flood the terminal.
228 log::debug!("Undeserializable response body: {}", body);
229 RemoteError::other(format!(
230 "invalid response JSON: {} (body: {})",
231 e,
232 preview(&body, BODY_PREVIEW_BYTES)
233 ))
234 })?;
235
236 if !api_resp.success {
237 if let Some(err) = api_resp.error {
238 return Err(RemoteError::other(format!("{}: {}", err.code, err.message)));
239 }
240 return Err(RemoteError::other("request failed with no error details"));
241 }
242
243 api_resp
244 .data
245 .ok_or_else(|| RemoteError::other("response had success=true but no data"))
246 }
247
248 fn parse_error_body(&self, status: u16, body: &str) -> RemoteError {
249 // Try to parse as ApiResponse first.

Callers 4

getMethod · 0.80
postMethod · 0.80
post_emptyMethod · 0.80
putMethod · 0.80

Calls 5

check_min_version_headerFunction · 0.85
textMethod · 0.80
parse_error_bodyMethod · 0.80
statusMethod · 0.45
is_successMethod · 0.45

Tested by

no test coverage detected