Merge pull request #2297 from zed-industries/fix-random-panics

Mikayla Maki created

WIP: Fix random panics

Change summary

crates/collab_ui/src/contact_list.rs  | 12 +++++++-
crates/fs/src/repository.rs           | 37 +++++++++++++++++++++++++++-
crates/terminal/src/mappings/mouse.rs |  3 ++
3 files changed, 48 insertions(+), 4 deletions(-)

Detailed changes

crates/collab_ui/src/contact_list.rs 🔗

@@ -316,12 +316,20 @@ impl ContactList {
             github_login
         );
         let mut answer = cx.prompt(PromptLevel::Warning, &prompt_message, &["Remove", "Cancel"]);
+        let window_id = cx.window_id();
         cx.spawn(|_, mut cx| async move {
             if answer.next().await == Some(0) {
-                user_store
+                if let Err(e) = user_store
                     .update(&mut cx, |store, cx| store.remove_contact(user_id, cx))
                     .await
-                    .unwrap();
+                {
+                    cx.prompt(
+                        window_id,
+                        PromptLevel::Info,
+                        &format!("Failed to remove contact: {}", e),
+                        &["Ok"],
+                    );
+                }
             }
         })
         .detach();

crates/fs/src/repository.rs 🔗

@@ -2,7 +2,7 @@ use anyhow::Result;
 use collections::HashMap;
 use parking_lot::Mutex;
 use std::{
-    path::{Path, PathBuf},
+    path::{Component, Path, PathBuf},
     sync::Arc,
 };
 
@@ -27,7 +27,11 @@ impl GitRepository for LibGitRepository {
         fn logic(repo: &LibGitRepository, relative_file_path: &Path) -> Result<Option<String>> {
             const STAGE_NORMAL: i32 = 0;
             let index = repo.index()?;
-            let oid = match index.get_path(relative_file_path, STAGE_NORMAL) {
+
+            // This check is required because index.get_path() unwraps internally :(
+            check_path_to_repo_path_errors(relative_file_path)?;
+
+            let oid = match index.get_path(&relative_file_path, STAGE_NORMAL) {
                 Some(entry) => entry.id,
                 None => return Ok(None),
             };
@@ -69,3 +73,32 @@ impl GitRepository for FakeGitRepository {
         state.index_contents.get(path).cloned()
     }
 }
+
+fn check_path_to_repo_path_errors(relative_file_path: &Path) -> Result<()> {
+    match relative_file_path.components().next() {
+        None => anyhow::bail!("repo path should not be empty"),
+        Some(Component::Prefix(_)) => anyhow::bail!(
+            "repo path `{}` should be relative, not a windows prefix",
+            relative_file_path.to_string_lossy()
+        ),
+        Some(Component::RootDir) => {
+            anyhow::bail!(
+                "repo path `{}` should be relative",
+                relative_file_path.to_string_lossy()
+            )
+        }
+        Some(Component::CurDir) => {
+            anyhow::bail!(
+                "repo path `{}` should not start with `.`",
+                relative_file_path.to_string_lossy()
+            )
+        }
+        Some(Component::ParentDir) => {
+            anyhow::bail!(
+                "repo path `{}` should not start with `..`",
+                relative_file_path.to_string_lossy()
+            )
+        }
+        _ => Ok(()),
+    }
+}

crates/terminal/src/mappings/mouse.rs 🔗

@@ -186,6 +186,9 @@ pub fn mouse_moved_report(point: Point, e: &MouseMovedEvent, mode: TermMode) ->
 }
 
 pub fn mouse_side(pos: Vector2F, cur_size: TerminalSize) -> alacritty_terminal::index::Direction {
+    if cur_size.cell_width as usize == 0 {
+        return Side::Right;
+    }
     let x = pos.0.x() as usize;
     let cell_x = x.saturating_sub(cur_size.cell_width as usize) % cur_size.cell_width as usize;
     let half_cell_width = (cur_size.cell_width / 2.0) as usize;