workspace: Fix not able to close tab when buffer save fails (#35589)

Smit Barmase and Lukas Wirth created

Closes #26216, Closes #35517

Now we prompt user if buffer save failed, asking them to close without
saving or cancel the action.

Release Notes:

- Fixed issue where closing read-only or deleted buffer would not close
that tab.

Co-authored-by: Lukas Wirth <lukas@zed.dev>

Change summary

crates/workspace/src/pane.rs | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)

Detailed changes

crates/workspace/src/pane.rs 🔗

@@ -1664,10 +1664,33 @@ impl Pane {
                 }
 
                 if should_save {
-                    if !Self::save_item(project.clone(), &pane, &*item_to_close, save_intent, cx)
-                        .await?
+                    match Self::save_item(project.clone(), &pane, &*item_to_close, save_intent, cx)
+                        .await
                     {
-                        break;
+                        Ok(success) => {
+                            if !success {
+                                break;
+                            }
+                        }
+                        Err(err) => {
+                            let answer = pane.update_in(cx, |_, window, cx| {
+                                let detail = Self::file_names_for_prompt(
+                                    &mut [&item_to_close].into_iter(),
+                                    cx,
+                                );
+                                window.prompt(
+                                    PromptLevel::Warning,
+                                    &format!("Unable to save file: {}", &err),
+                                    Some(&detail),
+                                    &["Close Without Saving", "Cancel"],
+                                    cx,
+                                )
+                            })?;
+                            match answer.await {
+                                Ok(0) => {}
+                                Ok(1..) | Err(_) => break,
+                            }
+                        }
                     }
                 }