fix: better offline handling

This commit is contained in:
Calum H. (IMB11)
2026-07-27 15:39:52 +01:00
parent c8b21fe120
commit 08bb4de9dc
12 changed files with 156 additions and 34 deletions
@@ -713,9 +713,17 @@ where
let body = match response.text().await {
Ok(body) => body,
Err(error) if strip_response_url => {
return Err(error.without_url().into());
return Err(crate::ErrorKind::SharedInstancesApiError(
error.without_url().to_string(),
)
.into());
}
Err(error) => {
return Err(crate::ErrorKind::SharedInstancesApiError(
error.to_string(),
)
.into());
}
Err(error) => return Err(error.into()),
};
serde_json::from_str::<T>(&body).map_err(|error| {
tracing::warn!(
@@ -729,7 +737,7 @@ where
error_column = error.column(),
"Shared instances API returned an invalid JSON response"
);
crate::ErrorKind::OtherError(format!(
crate::ErrorKind::SharedInstancesApiError(format!(
"Shared instances API request {operation} {method} {log_path} returned invalid JSON with status {status}"
))
.into()
@@ -870,7 +878,12 @@ pub(super) async fn send_bytes_request_to_url(
.header(reqwest::header::CONTENT_TYPE, "application/octet-stream")
.body(body)
.send()
.await?;
.await
.map_err(|error| {
crate::ErrorKind::SharedInstancesApiError(
error.without_url().to_string(),
)
})?;
if response.status().is_success() {
let request_id = response_request_id(&response);
@@ -960,9 +973,17 @@ async fn send_request_with_auth_and_log_path(
let response = match request.send().await {
Ok(response) => response,
Err(error) if path != log_path => {
return Err(error.without_url().into());
return Err(crate::ErrorKind::SharedInstancesApiError(
error.without_url().to_string(),
)
.into());
}
Err(error) => {
return Err(crate::ErrorKind::SharedInstancesApiError(
error.to_string(),
)
.into());
}
Err(error) => return Err(error.into()),
};
if response.status().is_success() {
let request_id = response_request_id(&response);
@@ -995,10 +1016,14 @@ pub(super) async fn shared_instances_request_error<T>(
request_id = request_id.as_deref().unwrap_or("none"),
"Shared instances API request failed"
);
Err(crate::ErrorKind::OtherError(format!(
let message = format!(
"Shared instances API request {operation} {method} {path} failed with status {status}"
))
.into())
);
if status.is_server_error() {
return Err(crate::ErrorKind::SharedInstancesApiError(message).into());
}
Err(crate::ErrorKind::OtherError(message).into())
}
pub(super) fn response_request_id(
@@ -244,13 +244,7 @@ pub(crate) async fn check_shared_instance_availability_before_launch(
let availability =
match get_remote_instance_access(&attachment.id, state).await {
Ok(availability) => availability,
Err(error)
if matches!(
error.raw.as_ref(),
crate::ErrorKind::NoCredentialsError
| crate::ErrorKind::FetchError(_)
) =>
{
Err(error) => {
tracing::warn!(
instance_id,
shared_instance_id = %attachment.id,
@@ -259,7 +253,6 @@ pub(crate) async fn check_shared_instance_availability_before_launch(
);
return Ok(());
}
Err(error) => return Err(error),
};
if let SharedInstanceRemoteResponse::Unavailable(reason) = availability {
+3
View File
@@ -124,6 +124,9 @@ pub enum ErrorKind {
#[error("Shared instance unavailable: {0}")]
SharedInstanceUnavailable(SharedInstanceUnavailableReason),
#[error("Shared instances API request failed: {0}")]
SharedInstancesApiError(String),
#[error("Join handle error: {0}")]
JoinError(#[from] tokio::task::JoinError),
+1
View File
@@ -1293,6 +1293,7 @@ fn install_error_code(
ErrorKind::SharedInstanceUnavailable(_) => {
"shared_instance_unavailable"
}
ErrorKind::SharedInstancesApiError(_) => "shared_instances_api_error",
ErrorKind::InputError(_) => match phase {
PreparingInstance | Finalizing => "instance_error",
ResolvingPack | DownloadingPackFile | ReadingPackManifest => {