auto_update: Show update error on hover and open logs on click (#38241)

Release Notes:

- Improved error reporting when auto-updating fails
This commit is contained in:
Lukas Wirth 2025-09-16 10:07:02 +02:00 committed by GitHub
parent 1c09985fb3
commit f321d02207
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 32 additions and 32 deletions

View file

@ -1,4 +1,4 @@
use auto_update::{AutoUpdateStatus, AutoUpdater, DismissErrorMessage, VersionCheckType}; use auto_update::{AutoUpdateStatus, AutoUpdater, DismissMessage, VersionCheckType};
use editor::Editor; use editor::Editor;
use extension_host::{ExtensionOperation, ExtensionStore}; use extension_host::{ExtensionOperation, ExtensionStore};
use futures::StreamExt; use futures::StreamExt;
@ -280,18 +280,13 @@ impl ActivityIndicator {
}); });
} }
fn dismiss_error_message( fn dismiss_message(&mut self, _: &DismissMessage, _: &mut Window, cx: &mut Context<Self>) {
&mut self, let dismissed = if let Some(updater) = &self.auto_updater {
_: &DismissErrorMessage, updater.update(cx, |updater, cx| updater.dismiss(cx))
_: &mut Window,
cx: &mut Context<Self>,
) {
let error_dismissed = if let Some(updater) = &self.auto_updater {
updater.update(cx, |updater, cx| updater.dismiss_error(cx))
} else { } else {
false false
}; };
if error_dismissed { if dismissed {
return; return;
} }
@ -513,7 +508,7 @@ impl ActivityIndicator {
on_click: Some(Arc::new(move |this, window, cx| { on_click: Some(Arc::new(move |this, window, cx| {
this.statuses this.statuses
.retain(|status| !downloading.contains(&status.name)); .retain(|status| !downloading.contains(&status.name));
this.dismiss_error_message(&DismissErrorMessage, window, cx) this.dismiss_message(&DismissMessage, window, cx)
})), })),
tooltip_message: None, tooltip_message: None,
}); });
@ -542,7 +537,7 @@ impl ActivityIndicator {
on_click: Some(Arc::new(move |this, window, cx| { on_click: Some(Arc::new(move |this, window, cx| {
this.statuses this.statuses
.retain(|status| !checking_for_update.contains(&status.name)); .retain(|status| !checking_for_update.contains(&status.name));
this.dismiss_error_message(&DismissErrorMessage, window, cx) this.dismiss_message(&DismissMessage, window, cx)
})), })),
tooltip_message: None, tooltip_message: None,
}); });
@ -650,13 +645,14 @@ impl ActivityIndicator {
.and_then(|updater| match &updater.read(cx).status() { .and_then(|updater| match &updater.read(cx).status() {
AutoUpdateStatus::Checking => Some(Content { AutoUpdateStatus::Checking => Some(Content {
icon: Some( icon: Some(
Icon::new(IconName::Download) Icon::new(IconName::LoadCircle)
.size(IconSize::Small) .size(IconSize::Small)
.with_rotate_animation(3)
.into_any_element(), .into_any_element(),
), ),
message: "Checking for Zed updates…".to_string(), message: "Checking for Zed updates…".to_string(),
on_click: Some(Arc::new(|this, window, cx| { on_click: Some(Arc::new(|this, window, cx| {
this.dismiss_error_message(&DismissErrorMessage, window, cx) this.dismiss_message(&DismissMessage, window, cx)
})), })),
tooltip_message: None, tooltip_message: None,
}), }),
@ -668,19 +664,20 @@ impl ActivityIndicator {
), ),
message: "Downloading Zed update…".to_string(), message: "Downloading Zed update…".to_string(),
on_click: Some(Arc::new(|this, window, cx| { on_click: Some(Arc::new(|this, window, cx| {
this.dismiss_error_message(&DismissErrorMessage, window, cx) this.dismiss_message(&DismissMessage, window, cx)
})), })),
tooltip_message: Some(Self::version_tooltip_message(version)), tooltip_message: Some(Self::version_tooltip_message(version)),
}), }),
AutoUpdateStatus::Installing { version } => Some(Content { AutoUpdateStatus::Installing { version } => Some(Content {
icon: Some( icon: Some(
Icon::new(IconName::Download) Icon::new(IconName::LoadCircle)
.size(IconSize::Small) .size(IconSize::Small)
.with_rotate_animation(3)
.into_any_element(), .into_any_element(),
), ),
message: "Installing Zed update…".to_string(), message: "Installing Zed update…".to_string(),
on_click: Some(Arc::new(|this, window, cx| { on_click: Some(Arc::new(|this, window, cx| {
this.dismiss_error_message(&DismissErrorMessage, window, cx) this.dismiss_message(&DismissMessage, window, cx)
})), })),
tooltip_message: Some(Self::version_tooltip_message(version)), tooltip_message: Some(Self::version_tooltip_message(version)),
}), }),
@ -690,17 +687,18 @@ impl ActivityIndicator {
on_click: Some(Arc::new(move |_, _, cx| workspace::reload(cx))), on_click: Some(Arc::new(move |_, _, cx| workspace::reload(cx))),
tooltip_message: Some(Self::version_tooltip_message(version)), tooltip_message: Some(Self::version_tooltip_message(version)),
}), }),
AutoUpdateStatus::Errored => Some(Content { AutoUpdateStatus::Errored { error } => Some(Content {
icon: Some( icon: Some(
Icon::new(IconName::Warning) Icon::new(IconName::Warning)
.size(IconSize::Small) .size(IconSize::Small)
.into_any_element(), .into_any_element(),
), ),
message: "Auto update failed".to_string(), message: "Failed to update Zed".to_string(),
on_click: Some(Arc::new(|this, window, cx| { on_click: Some(Arc::new(|this, window, cx| {
this.dismiss_error_message(&DismissErrorMessage, window, cx) window.dispatch_action(Box::new(workspace::OpenLog), cx);
this.dismiss_message(&DismissMessage, window, cx);
})), })),
tooltip_message: None, tooltip_message: Some(format!("{error}")),
}), }),
AutoUpdateStatus::Idle => None, AutoUpdateStatus::Idle => None,
}) })
@ -738,7 +736,7 @@ impl ActivityIndicator {
})), })),
message, message,
on_click: Some(Arc::new(|this, window, cx| { on_click: Some(Arc::new(|this, window, cx| {
this.dismiss_error_message(&Default::default(), window, cx) this.dismiss_message(&Default::default(), window, cx)
})), })),
tooltip_message: None, tooltip_message: None,
}) })
@ -777,7 +775,7 @@ impl Render for ActivityIndicator {
let result = h_flex() let result = h_flex()
.id("activity-indicator") .id("activity-indicator")
.on_action(cx.listener(Self::show_error_message)) .on_action(cx.listener(Self::show_error_message))
.on_action(cx.listener(Self::dismiss_error_message)); .on_action(cx.listener(Self::dismiss_message));
let Some(content) = self.content_to_render(cx) else { let Some(content) = self.content_to_render(cx) else {
return result; return result;
}; };

View file

@ -34,7 +34,7 @@ actions!(
/// Checks for available updates. /// Checks for available updates.
Check, Check,
/// Dismisses the update error message. /// Dismisses the update error message.
DismissErrorMessage, DismissMessage,
/// Opens the release notes for the current version in a browser. /// Opens the release notes for the current version in a browser.
ViewReleaseNotes, ViewReleaseNotes,
] ]
@ -55,14 +55,14 @@ pub enum VersionCheckType {
Semantic(SemanticVersion), Semantic(SemanticVersion),
} }
#[derive(Clone, PartialEq, Eq)] #[derive(Clone)]
pub enum AutoUpdateStatus { pub enum AutoUpdateStatus {
Idle, Idle,
Checking, Checking,
Downloading { version: VersionCheckType }, Downloading { version: VersionCheckType },
Installing { version: VersionCheckType }, Installing { version: VersionCheckType },
Updated { version: VersionCheckType }, Updated { version: VersionCheckType },
Errored, Errored { error: Arc<anyhow::Error> },
} }
impl AutoUpdateStatus { impl AutoUpdateStatus {
@ -383,7 +383,9 @@ impl AutoUpdater {
} }
UpdateCheckType::Manual => { UpdateCheckType::Manual => {
log::error!("auto-update failed: error:{:?}", error); log::error!("auto-update failed: error:{:?}", error);
AutoUpdateStatus::Errored AutoUpdateStatus::Errored {
error: Arc::new(error),
}
} }
}; };
@ -402,8 +404,8 @@ impl AutoUpdater {
self.status.clone() self.status.clone()
} }
pub fn dismiss_error(&mut self, cx: &mut Context<Self>) -> bool { pub fn dismiss(&mut self, cx: &mut Context<Self>) -> bool {
if self.status == AutoUpdateStatus::Idle { if let AutoUpdateStatus::Idle = self.status {
return false; return false;
} }
self.status = AutoUpdateStatus::Idle; self.status = AutoUpdateStatus::Idle;

View file

@ -637,9 +637,9 @@ impl TitleBar {
Some(AutoUpdateStatus::Installing { .. }) Some(AutoUpdateStatus::Installing { .. })
| Some(AutoUpdateStatus::Downloading { .. }) | Some(AutoUpdateStatus::Downloading { .. })
| Some(AutoUpdateStatus::Checking) => "Updating...", | Some(AutoUpdateStatus::Checking) => "Updating...",
Some(AutoUpdateStatus::Idle) | Some(AutoUpdateStatus::Errored) | None => { Some(AutoUpdateStatus::Idle)
"Please update Zed to Collaborate" | Some(AutoUpdateStatus::Errored { .. })
} | None => "Please update Zed to Collaborate",
}; };
Some( Some(