From 95691577439aa309c5b8fefafa0ca60d66f79543 Mon Sep 17 00:00:00 2001 From: KyleBarton Date: Fri, 23 Jan 2026 13:22:08 -0800 Subject: [PATCH] Clean up error handling for some edge cases to prevent panic (#47513) Release Notes: - Improved error handling in the dev container crate to prevent panics --- crates/dev_container/src/lib.rs | 44 +++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/crates/dev_container/src/lib.rs b/crates/dev_container/src/lib.rs index d6ef63781632c36839c81fe47683bb4269e34e7a..e670b0e8339ea2ca10575f99529d6e86c702980e 100644 --- a/crates/dev_container/src/lib.rs +++ b/crates/dev_container/src/lib.rs @@ -1,6 +1,7 @@ use gpui::AppContext; use gpui::Entity; use gpui::Task; +use http_client::anyhow; use picker::Picker; use picker::PickerDelegate; use settings::RegisterSetting; @@ -279,7 +280,7 @@ impl PickerDelegate for TemplatePickerDelegate { cx, ); }) - .log_err(); + .ok(); } fn dismissed(&mut self, window: &mut Window, cx: &mut Context>) { @@ -287,7 +288,7 @@ impl PickerDelegate for TemplatePickerDelegate { .update(cx, |modal, cx| { modal.dismiss(&menu::Cancel, window, cx); }) - .log_err(); + .ok(); } fn render_match( @@ -444,7 +445,7 @@ impl PickerDelegate for FeaturePickerDelegate { .update(cx, |modal, cx| { (self.on_confirm)(self.template_entry.clone(), modal, window, cx) }) - .log_err(); + .ok(); } else { let current = &mut self.candidate_features[self.matching_indices[self.selected_index]]; current.toggle_state = match current.toggle_state { @@ -469,7 +470,7 @@ impl PickerDelegate for FeaturePickerDelegate { .update(cx, |modal, cx| { modal.dismiss(&menu::Cancel, window, cx); }) - .log_err(); + .ok(); } fn render_match( @@ -994,7 +995,9 @@ impl StatefulModal for DevContainerModal { let new_state = match message { DevContainerMessage::SearchTemplates => { cx.spawn_in(window, async move |this, cx| { - let client = cx.update(|_, cx| cx.http_client()).unwrap(); + let Ok(client) = cx.update(|_, cx| cx.http_client()) else { + return; + }; match get_templates(client).await { Ok(templates) => { let message = @@ -1002,14 +1005,14 @@ impl StatefulModal for DevContainerModal { this.update_in(cx, |this, window, cx| { this.accept_message(message, window, cx); }) - .log_err(); + .ok(); } Err(e) => { let message = DevContainerMessage::ErrorRetrievingTemplates(e); this.update_in(cx, |this, window, cx| { this.accept_message(message, window, cx); }) - .log_err(); + .ok(); } } }) @@ -1158,7 +1161,9 @@ impl StatefulModal for DevContainerModal { } DevContainerMessage::TemplateOptionsCompleted(template_entry) => { cx.spawn_in(window, async move |this, cx| { - let client = cx.update(|_, cx| cx.http_client()).unwrap(); + let Ok(client) = cx.update(|_, cx| cx.http_client()) else { + return; + }; let Some(features) = get_features(client).await.log_err() else { return; }; @@ -1166,7 +1171,7 @@ impl StatefulModal for DevContainerModal { this.update_in(cx, |this, window, cx| { this.accept_message(message, window, cx); }) - .log_err(); + .ok(); }) .detach(); Some(DevContainerState::QueryingFeatures(template_entry)) @@ -1438,7 +1443,7 @@ fn dispatch_apply_templates( cx, ); }) - .log_err(); + .ok(); return; } @@ -1460,7 +1465,7 @@ fn dispatch_apply_templates( cx, ); }) - .log_err(); + .ok(); return; } }; @@ -1471,10 +1476,14 @@ fn dispatch_apply_templates( { let Some(workspace_task) = workspace .update_in(cx, |workspace, window, cx| { - let path = RelPath::unix(".devcontainer/devcontainer.json").unwrap(); + let Ok(path) = RelPath::unix(".devcontainer/devcontainer.json") else { + return Task::ready(Err(anyhow!( + "Couldn't create path for .devcontainer/devcontainer.json" + ))); + }; workspace.open_path((tree_id, path), None, true, window, cx) }) - .log_err() + .ok() else { return; }; @@ -1484,7 +1493,7 @@ fn dispatch_apply_templates( this.update_in(cx, |this, window, cx| { this.dismiss(&menu::Cancel, window, cx); }) - .unwrap(); + .ok(); } else { return; } @@ -1597,11 +1606,14 @@ async fn get_deserialized_response( where T: for<'de> Deserialize<'de>, { - let request = Request::get(url) + let request = match Request::get(url) .header("Authorization", format!("Bearer {}", token)) .header("Accept", "application/vnd.oci.image.manifest.v1+json") .body(AsyncBody::default()) - .unwrap(); + { + Ok(request) => request, + Err(e) => return Err(format!("Failed to create request: {}", e)), + }; let response = match client.send(request).await { Ok(response) => response, Err(e) => {