git_ui: Improve error handling in commit message generation (#29005)

After and Before video of the issue and solution.


https://github.com/user-attachments/assets/40508f20-5549-4b3d-9331-85b8192a5b5a



Closes #27319

Release Notes:

- Provide Feedback on commit message generation error

---------

Signed-off-by: Umesh Yadav <umesh4257@gmail.com>
Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
Umesh Yadav 2025-06-09 19:50:19 +05:30 committed by GitHub
parent 047a7f5d29
commit 3853e83da7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -27,7 +27,7 @@ use git::status::StageStatus;
use git::{Amend, ToggleStaged, repository::RepoPath, status::FileStatus}; use git::{Amend, ToggleStaged, repository::RepoPath, status::FileStatus};
use git::{ExpandCommitEditor, RestoreTrackedFiles, StageAll, TrashUntrackedFiles, UnstageAll}; use git::{ExpandCommitEditor, RestoreTrackedFiles, StageAll, TrashUntrackedFiles, UnstageAll};
use gpui::{ use gpui::{
Action, Animation, AnimationExt as _, AsyncWindowContext, Axis, ClickEvent, Corner, Action, Animation, AnimationExt as _, AsyncApp, AsyncWindowContext, Axis, ClickEvent, Corner,
DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, KeyContext, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, KeyContext,
ListHorizontalSizingBehavior, ListSizingBehavior, Modifiers, ModifiersChangedEvent, ListHorizontalSizingBehavior, ListSizingBehavior, Modifiers, ModifiersChangedEvent,
MouseButton, MouseDownEvent, Point, PromptLevel, ScrollStrategy, Subscription, Task, MouseButton, MouseDownEvent, Point, PromptLevel, ScrollStrategy, Subscription, Task,
@ -68,7 +68,7 @@ use util::{ResultExt, TryFutureExt, maybe};
use workspace::{ use workspace::{
Workspace, Workspace,
dock::{DockPosition, Panel, PanelEvent}, dock::{DockPosition, Panel, PanelEvent},
notifications::DetachAndPromptErr, notifications::{DetachAndPromptErr, ErrorMessagePrompt, NotificationId},
}; };
use zed_llm_client::CompletionIntent; use zed_llm_client::CompletionIntent;
@ -1779,7 +1779,19 @@ impl GitPanel {
this.generate_commit_message_task.take(); this.generate_commit_message_task.take();
}); });
let mut diff_text = diff.await??; let mut diff_text = match diff.await {
Ok(result) => match result {
Ok(text) => text,
Err(e) => {
Self::show_commit_message_error(&this, &e, cx);
return anyhow::Ok(());
}
},
Err(e) => {
Self::show_commit_message_error(&this, &e, cx);
return anyhow::Ok(());
}
};
const ONE_MB: usize = 1_000_000; const ONE_MB: usize = 1_000_000;
if diff_text.len() > ONE_MB { if diff_text.len() > ONE_MB {
@ -1817,26 +1829,37 @@ impl GitPanel {
}; };
let stream = model.stream_completion_text(request, &cx); let stream = model.stream_completion_text(request, &cx);
let mut messages = stream.await?; match stream.await {
Ok(mut messages) => {
if !text_empty {
this.update(cx, |this, cx| {
this.commit_message_buffer(cx).update(cx, |buffer, cx| {
let insert_position = buffer.anchor_before(buffer.len());
buffer.edit([(insert_position..insert_position, "\n")], None, cx)
});
})?;
}
if !text_empty { while let Some(message) = messages.stream.next().await {
this.update(cx, |this, cx| { match message {
this.commit_message_buffer(cx).update(cx, |buffer, cx| { Ok(text) => {
let insert_position = buffer.anchor_before(buffer.len()); this.update(cx, |this, cx| {
buffer.edit([(insert_position..insert_position, "\n")], None, cx) this.commit_message_buffer(cx).update(cx, |buffer, cx| {
}); let insert_position = buffer.anchor_before(buffer.len());
})?; buffer.edit([(insert_position..insert_position, text)], None, cx);
} });
})?;
while let Some(message) = messages.stream.next().await { }
let text = message?; Err(e) => {
Self::show_commit_message_error(&this, &e, cx);
this.update(cx, |this, cx| { break;
this.commit_message_buffer(cx).update(cx, |buffer, cx| { }
let insert_position = buffer.anchor_before(buffer.len()); }
buffer.edit([(insert_position..insert_position, text)], None, cx); }
}); }
})?; Err(e) => {
Self::show_commit_message_error(&this, &e, cx);
}
} }
anyhow::Ok(()) anyhow::Ok(())
@ -2694,6 +2717,26 @@ impl GitPanel {
} }
} }
fn show_commit_message_error<E>(weak_this: &WeakEntity<Self>, err: &E, cx: &mut AsyncApp)
where
E: std::fmt::Debug + std::fmt::Display,
{
if let Ok(Some(workspace)) = weak_this.update(cx, |this, _cx| this.workspace.upgrade()) {
let _ = workspace.update(cx, |workspace, cx| {
struct CommitMessageError;
let notification_id = NotificationId::unique::<CommitMessageError>();
workspace.show_notification(notification_id, cx, |cx| {
cx.new(|cx| {
ErrorMessagePrompt::new(
format!("Failed to generate commit message: {err}"),
cx,
)
})
});
});
}
}
fn show_remote_output(&self, action: RemoteAction, info: RemoteCommandOutput, cx: &mut App) { fn show_remote_output(&self, action: RemoteAction, info: RemoteCommandOutput, cx: &mut App) {
let Some(workspace) = self.workspace.upgrade() else { let Some(workspace) = self.workspace.upgrade() else {
return; return;