diff options
author | Ellie Huxtable <ellie@elliehuxtable.com> | 2024-01-15 12:57:28 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-15 12:57:28 +0000 |
commit | ecce55b445dd782aed0f38a05724eeba0653f379 (patch) | |
tree | cba17aea91cb069a0c93cd19647e206cc993a078 | |
parent | 69ec99111847b2da6405966aae343c156275f309 (diff) |
feat: add better error handling for sync (#1572)
Hopefully this helps users get more descriptive errors, and give more
descriptive bug reports
-rw-r--r-- | atuin-client/src/api_client.rs | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/atuin-client/src/api_client.rs b/atuin-client/src/api_client.rs index d428d6b8..7b373599 100644 --- a/atuin-client/src/api_client.rs +++ b/atuin-client/src/api_client.rs @@ -143,6 +143,28 @@ pub fn ensure_version(response: &Response) -> Result<bool> { Ok(true) } +async fn handle_resp_error(resp: Response) -> Result<Response> { + let status = resp.status(); + + if status == StatusCode::SERVICE_UNAVAILABLE { + bail!( + "Service unavailable: check https://status.atuin.sh (or get in touch with your host)" + ); + } + + if status.is_client_error() { + let error = resp.json::<ErrorResponse>().await?.reason; + bail!("Could not fetch history, client error: {error}.") + } else if status.is_server_error() { + let error = resp.json::<ErrorResponse>().await?.reason; + bail!("There was an error with the atuin sync service: {error}.\nIf the problem persists, contact the host") + } else if !status.is_success() { + bail!("There was an error with the atuin sync service: Status {status:?}.\nIf the problem persists, contact the host") + } + + Ok(resp) +} + impl<'a> Client<'a> { pub fn new( sync_addr: &'a str, @@ -172,6 +194,7 @@ impl<'a> Client<'a> { let url = Url::parse(url.as_str())?; let resp = self.client.get(url).send().await?; + let resp = handle_resp_error(resp).await?; if !ensure_version(&resp)? { bail!("could not sync due to version mismatch"); @@ -191,15 +214,12 @@ impl<'a> Client<'a> { let url = Url::parse(url.as_str())?; let resp = self.client.get(url).send().await?; + let resp = handle_resp_error(resp).await?; if !ensure_version(&resp)? { bail!("could not sync due to version mismatch"); } - if resp.status() != StatusCode::OK { - bail!("failed to get status (are you logged in?)"); - } - let status = resp.json::<StatusResponse>().await?; Ok(status) @@ -228,27 +248,18 @@ impl<'a> Client<'a> { ); let resp = self.client.get(url).send().await?; + let resp = handle_resp_error(resp).await?; - let status = resp.status(); - if status.is_success() { - let history = resp.json::<SyncHistoryResponse>().await?; - Ok(history) - } else if status.is_client_error() { - let error = resp.json::<ErrorResponse>().await?.reason; - bail!("Could not fetch history: {error}.") - } else if status.is_server_error() { - let error = resp.json::<ErrorResponse>().await?.reason; - bail!("There was an error with the atuin sync service: {error}.\nIf the problem persists, contact the host") - } else { - bail!("There was an error with the atuin sync service: Status {status:?}.\nIf the problem persists, contact the host") - } + let history = resp.json::<SyncHistoryResponse>().await?; + Ok(history) } pub async fn post_history(&self, history: &[AddHistoryRequest]) -> Result<()> { let url = format!("{}/history", self.sync_addr); let url = Url::parse(url.as_str())?; - self.client.post(url).json(history).send().await?; + let resp = self.client.post(url).json(history).send().await?; + handle_resp_error(resp).await?; Ok(()) } @@ -257,7 +268,8 @@ impl<'a> Client<'a> { let url = format!("{}/history", self.sync_addr); let url = Url::parse(url.as_str())?; - self.client + let resp = self + .client .delete(url) .json(&DeleteHistoryRequest { client_id: h.id.to_string(), @@ -265,6 +277,8 @@ impl<'a> Client<'a> { .send() .await?; + handle_resp_error(resp).await?; + Ok(()) } @@ -273,14 +287,7 @@ impl<'a> Client<'a> { let url = Url::parse(url.as_str())?; let resp = self.client.post(url).json(records).send().await?; - info!("posted records, got {}", resp.status()); - - if !resp.status().is_success() { - error!( - "failed to post records to server; got: {:?}", - resp.text().await - ); - } + handle_resp_error(resp).await?; Ok(()) } @@ -307,6 +314,7 @@ impl<'a> Client<'a> { let url = Url::parse(url.as_str())?; let resp = self.client.get(url).send().await?; + let resp = handle_resp_error(resp).await?; let records = resp.json::<Vec<Record<EncryptedData>>>().await?; @@ -318,6 +326,7 @@ impl<'a> Client<'a> { let url = Url::parse(url.as_str())?; let resp = self.client.get(url).send().await?; + let resp = handle_resp_error(resp).await?; if !ensure_version(&resp)? { bail!("could not sync records due to version mismatch"); |