fix(remote): surface HTTP and registry errors

- Map HTTP 404 to RemoteError::NotFound; propagate other HTTP errors\n- Fail push when the remote registry payload is invalid
This commit is contained in:
Marco Allegretti 2026-02-25 13:46:40 +01:00
parent f320608175
commit 8feee8048c
2 changed files with 34 additions and 8 deletions

View file

@ -56,7 +56,28 @@ impl HttpBackend {
if let Some(ref token) = self.config.auth_token { if let Some(ref token) = self.config.auth_token {
req = req.header("Authorization", &format!("Bearer {token}")); req = req.header("Authorization", &format!("Bearer {token}"));
} }
let resp = req.call().map_err(|e| RemoteError::Http(e.to_string()))?; let resp = match req.call() {
Ok(r) => r,
Err(ureq::Error::StatusCode(404)) => {
return Err(RemoteError::NotFound(url.to_owned()));
}
Err(ureq::Error::StatusCode(code)) => {
return Err(RemoteError::Http(format!("HTTP {code} for {url}")));
}
Err(e) => {
return Err(RemoteError::Http(e.to_string()));
}
};
let status = resp.status();
let code = status.as_u16();
if code == 404 {
return Err(RemoteError::NotFound(url.to_owned()));
}
if code >= 400 {
return Err(RemoteError::Http(format!("HTTP {code} for {url}")));
}
let mut reader = resp.into_body().into_reader(); let mut reader = resp.into_body().into_reader();
let mut body = Vec::new(); let mut body = Vec::new();
reader reader
@ -73,8 +94,11 @@ impl HttpBackend {
if let Some(ref token) = self.config.auth_token { if let Some(ref token) = self.config.auth_token {
req = req.header("Authorization", &format!("Bearer {token}")); req = req.header("Authorization", &format!("Bearer {token}"));
} }
let resp = req.call().map_err(|e| RemoteError::Http(e.to_string()))?; match req.call() {
Ok(resp.status().into()) Ok(resp) => Ok(resp.status().into()),
Err(ureq::Error::StatusCode(code)) => Ok(code),
Err(e) => Err(RemoteError::Http(e.to_string())),
}
} }
} }
@ -94,9 +118,10 @@ impl RemoteBackend for HttpBackend {
fn has_blob(&self, kind: BlobKind, key: &str) -> Result<bool, RemoteError> { fn has_blob(&self, kind: BlobKind, key: &str) -> Result<bool, RemoteError> {
let url = self.url(kind, key); let url = self.url(kind, key);
tracing::debug!("HEAD {url}"); tracing::debug!("HEAD {url}");
match self.do_head(&url) { match self.do_head(&url)? {
Ok(status) => Ok(status == 200), 200 => Ok(true),
Err(_) => Ok(false), 404 => Ok(false),
code => Err(RemoteError::Http(format!("HTTP {code} for HEAD {url}"))),
} }
} }

View file

@ -86,8 +86,9 @@ pub fn push_env(
// 7. Update registry if key provided // 7. Update registry if key provided
if let Some(key) = registry_key { if let Some(key) = registry_key {
let mut registry = match backend.get_registry() { let mut registry = match backend.get_registry() {
Ok(data) => Registry::from_bytes(&data).unwrap_or_default(), Ok(data) => Registry::from_bytes(&data)?,
Err(_) => Registry::new(), Err(RemoteError::NotFound(_)) => Registry::new(),
Err(e) => return Err(e),
}; };
registry.publish( registry.publish(
key, key,