Use anyhow
more idiomatically (#31052)
https://github.com/zed-industries/zed/issues/30972 brought up another case where our context is not enough to track the actual source of the issue: we get a general top-level error without inner error. The reason for this was `.ok_or_else(|| anyhow!("failed to read HEAD SHA"))?; ` on the top level. The PR finally reworks the way we use anyhow to reduce such issues (or at least make it simpler to bubble them up later in a fix). On top of that, uses a few more anyhow methods for better readability. * `.ok_or_else(|| anyhow!("..."))`, `map_err` and other similar error conversion/option reporting cases are replaced with `context` and `with_context` calls * in addition to that, various `anyhow!("failed to do ...")` are stripped with `.context("Doing ...")` messages instead to remove the parasitic `failed to` text * `anyhow::ensure!` is used instead of `if ... { return Err(...); }` calls * `anyhow::bail!` is used instead of `return Err(anyhow!(...));` Release Notes: - N/A
This commit is contained in:
parent
1e51a7ac44
commit
16366cf9f2
294 changed files with 2037 additions and 2610 deletions
|
@ -1316,7 +1316,7 @@ pub mod test {
|
|||
_project: &Entity<Project>,
|
||||
_path: &ProjectPath,
|
||||
_cx: &mut App,
|
||||
) -> Option<Task<gpui::Result<Entity<Self>>>> {
|
||||
) -> Option<Task<anyhow::Result<Entity<Self>>>> {
|
||||
None
|
||||
}
|
||||
fn entry_id(&self, _: &App) -> Option<ProjectEntryId> {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{SuppressNotification, Toast, Workspace};
|
||||
use anyhow::Context as _;
|
||||
use gpui::{
|
||||
AnyView, App, AppContext as _, AsyncWindowContext, ClickEvent, ClipboardItem, Context,
|
||||
DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, PromptLevel, Render, ScrollHandle,
|
||||
|
@ -239,9 +240,9 @@ impl LanguageServerPrompt {
|
|||
});
|
||||
|
||||
potential_future? // App Closed
|
||||
.ok_or_else(|| anyhow::anyhow!("Response already sent"))?
|
||||
.context("Response already sent")?
|
||||
.await
|
||||
.ok_or_else(|| anyhow::anyhow!("Stream already closed"))?;
|
||||
.context("Stream already closed")?;
|
||||
|
||||
this.update(cx, |_, cx| cx.emit(DismissEvent))?;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
pane_group::element::pane_axis,
|
||||
workspace_settings::{PaneSplitDirectionHorizontal, PaneSplitDirectionVertical},
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::Result;
|
||||
use call::{ActiveCall, ParticipantLocation};
|
||||
use collections::HashMap;
|
||||
use gpui::{
|
||||
|
@ -58,7 +58,7 @@ impl PaneGroup {
|
|||
self.root = Member::new_axis(old_pane.clone(), new_pane.clone(), direction);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!("Pane not found"))
|
||||
anyhow::bail!("Pane not found");
|
||||
}
|
||||
}
|
||||
Member::Axis(axis) => axis.split(old_pane, new_pane, direction),
|
||||
|
@ -538,7 +538,7 @@ impl PaneAxis {
|
|||
}
|
||||
}
|
||||
}
|
||||
Err(anyhow!("Pane not found"))
|
||||
anyhow::bail!("Pane not found");
|
||||
}
|
||||
|
||||
fn remove(&mut self, pane_to_remove: &Entity<Pane>) -> Result<Option<Member>> {
|
||||
|
@ -579,7 +579,7 @@ impl PaneAxis {
|
|||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Err(anyhow!("Pane not found"))
|
||||
anyhow::bail!("Pane not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
use anyhow::{Context, Result, anyhow, bail};
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
use client::DevServerProjectId;
|
||||
use db::{define_connection, query, sqlez::connection::Connection, sqlez_macros::sql};
|
||||
use gpui::{Axis, Bounds, Task, WindowBounds, WindowId, point, size};
|
||||
|
@ -181,7 +181,7 @@ impl Column for BreakpointStateWrapper<'_> {
|
|||
match state {
|
||||
0 => Ok((BreakpointState::Enabled.into(), start_index + 1)),
|
||||
1 => Ok((BreakpointState::Disabled.into(), start_index + 1)),
|
||||
_ => Err(anyhow::anyhow!("Invalid BreakpointState discriminant")),
|
||||
_ => anyhow::bail!("Invalid BreakpointState discriminant {state}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -914,7 +914,7 @@ impl WorkspaceDb {
|
|||
log::debug!("Inserting SSH project at host {host}");
|
||||
self.insert_ssh_project(host, port, paths, user)
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("failed to insert ssh project"))
|
||||
.context("failed to insert ssh project")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1244,7 +1244,7 @@ impl WorkspaceDb {
|
|||
*axis,
|
||||
flex_string,
|
||||
))?
|
||||
.ok_or_else(|| anyhow!("Couldn't retrieve group_id from inserted pane_group"))?;
|
||||
.context("Couldn't retrieve group_id from inserted pane_group")?;
|
||||
|
||||
for (position, group) in children.iter().enumerate() {
|
||||
Self::save_pane_group(conn, workspace_id, group, Some((group_id, position)))?
|
||||
|
@ -1270,7 +1270,7 @@ impl WorkspaceDb {
|
|||
VALUES (?, ?, ?)
|
||||
RETURNING pane_id
|
||||
))?((workspace_id, pane.active, pane.pinned_count))?
|
||||
.ok_or_else(|| anyhow!("Could not retrieve inserted pane_id"))?;
|
||||
.context("Could not retrieve inserted pane_id")?;
|
||||
|
||||
let (parent_id, order) = parent.unzip();
|
||||
conn.exec_bound(sql!(
|
||||
|
|
|
@ -1296,7 +1296,7 @@ impl Workspace {
|
|||
) -> Task<
|
||||
anyhow::Result<(
|
||||
WindowHandle<Workspace>,
|
||||
Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>,
|
||||
Vec<Option<anyhow::Result<Box<dyn ItemHandle>>>>,
|
||||
)>,
|
||||
> {
|
||||
let project_handle = Project::local(
|
||||
|
@ -2187,7 +2187,7 @@ impl Workspace {
|
|||
}
|
||||
|
||||
*keystrokes.borrow_mut() = Default::default();
|
||||
Err(anyhow!("over 100 keystrokes passed to send_keystrokes"))
|
||||
anyhow::bail!("over 100 keystrokes passed to send_keystrokes");
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
@ -2324,7 +2324,7 @@ impl Workspace {
|
|||
pane: Option<WeakEntity<Pane>>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>> {
|
||||
) -> Task<Vec<Option<anyhow::Result<Box<dyn ItemHandle>>>>> {
|
||||
log::info!("open paths {abs_paths:?}");
|
||||
|
||||
let fs = self.app_state.fs.clone();
|
||||
|
@ -3076,7 +3076,7 @@ impl Workspace {
|
|||
focus_item: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<Box<dyn ItemHandle>, anyhow::Error>> {
|
||||
) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
||||
self.open_path_preview(path, pane, focus_item, false, true, window, cx)
|
||||
}
|
||||
|
||||
|
@ -3089,7 +3089,7 @@ impl Workspace {
|
|||
activate: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<Box<dyn ItemHandle>, anyhow::Error>> {
|
||||
) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
||||
let pane = pane.unwrap_or_else(|| {
|
||||
self.last_active_center_pane.clone().unwrap_or_else(|| {
|
||||
self.panes
|
||||
|
@ -3127,7 +3127,7 @@ impl Workspace {
|
|||
path: impl Into<ProjectPath>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Box<dyn ItemHandle>, anyhow::Error>> {
|
||||
) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
||||
self.split_path_preview(path, false, None, window, cx)
|
||||
}
|
||||
|
||||
|
@ -3138,7 +3138,7 @@ impl Workspace {
|
|||
split_direction: Option<SplitDirection>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Box<dyn ItemHandle>, anyhow::Error>> {
|
||||
) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
||||
let pane = self.last_active_center_pane.clone().unwrap_or_else(|| {
|
||||
self.panes
|
||||
.first()
|
||||
|
@ -3178,7 +3178,7 @@ impl Workspace {
|
|||
))
|
||||
})
|
||||
})
|
||||
.map(|option| option.ok_or_else(|| anyhow!("pane was dropped")))?
|
||||
.map(|option| option.context("pane was dropped"))?
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -3938,12 +3938,12 @@ impl Workspace {
|
|||
let state = this
|
||||
.follower_states
|
||||
.get_mut(&leader_id)
|
||||
.ok_or_else(|| anyhow!("following interrupted"))?;
|
||||
.context("following interrupted")?;
|
||||
state.active_view_id = response
|
||||
.active_view
|
||||
.as_ref()
|
||||
.and_then(|view| ViewId::from_proto(view.id.clone()?).ok());
|
||||
Ok::<_, anyhow::Error>(())
|
||||
anyhow::Ok(())
|
||||
})??;
|
||||
if let Some(view) = response.active_view {
|
||||
Self::add_view_from_leader(this.clone(), leader_peer_id, &view, cx).await?;
|
||||
|
@ -4286,7 +4286,7 @@ impl Workspace {
|
|||
update: proto::UpdateFollowers,
|
||||
cx: &mut AsyncWindowContext,
|
||||
) -> Result<()> {
|
||||
match update.variant.ok_or_else(|| anyhow!("invalid update"))? {
|
||||
match update.variant.context("invalid update")? {
|
||||
proto::update_followers::Variant::CreateView(view) => {
|
||||
let view_id = ViewId::from_proto(view.id.clone().context("invalid view id")?)?;
|
||||
let should_add_view = this.update(cx, |this, _| {
|
||||
|
@ -4328,12 +4328,8 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
proto::update_followers::Variant::UpdateView(update_view) => {
|
||||
let variant = update_view
|
||||
.variant
|
||||
.ok_or_else(|| anyhow!("missing update view variant"))?;
|
||||
let id = update_view
|
||||
.id
|
||||
.ok_or_else(|| anyhow!("missing update view id"))?;
|
||||
let variant = update_view.variant.context("missing update view variant")?;
|
||||
let id = update_view.id.context("missing update view id")?;
|
||||
let mut tasks = Vec::new();
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
let project = this.project.clone();
|
||||
|
@ -4368,7 +4364,7 @@ impl Workspace {
|
|||
let this = this.upgrade().context("workspace dropped")?;
|
||||
|
||||
let Some(id) = view.id.clone() else {
|
||||
return Err(anyhow!("no id for view"));
|
||||
anyhow::bail!("no id for view");
|
||||
};
|
||||
let id = ViewId::from_proto(id)?;
|
||||
let panel_id = view.panel_id.and_then(proto::PanelId::from_i32);
|
||||
|
@ -4395,18 +4391,16 @@ impl Workspace {
|
|||
existing_item
|
||||
} else {
|
||||
let variant = view.variant.clone();
|
||||
if variant.is_none() {
|
||||
Err(anyhow!("missing view variant"))?;
|
||||
}
|
||||
anyhow::ensure!(variant.is_some(), "missing view variant");
|
||||
|
||||
let task = cx.update(|window, cx| {
|
||||
FollowableViewRegistry::from_state_proto(this.clone(), id, variant, window, cx)
|
||||
})?;
|
||||
|
||||
let Some(task) = task else {
|
||||
return Err(anyhow!(
|
||||
anyhow::bail!(
|
||||
"failed to construct view from leader (maybe from a different version of zed?)"
|
||||
));
|
||||
);
|
||||
};
|
||||
|
||||
let mut new_item = task.await?;
|
||||
|
@ -5099,7 +5093,7 @@ impl Workspace {
|
|||
) -> Result<()> {
|
||||
self.serializable_items_tx
|
||||
.unbounded_send(item)
|
||||
.map_err(|err| anyhow!("failed to send serializable item over channel: {}", err))
|
||||
.map_err(|err| anyhow!("failed to send serializable item over channel: {err}"))
|
||||
}
|
||||
|
||||
pub(crate) fn load_workspace(
|
||||
|
@ -6298,7 +6292,7 @@ impl ViewId {
|
|||
creator: message
|
||||
.creator
|
||||
.map(CollaboratorId::PeerId)
|
||||
.ok_or_else(|| anyhow!("creator is missing"))?,
|
||||
.context("creator is missing")?,
|
||||
id: message.id,
|
||||
})
|
||||
}
|
||||
|
@ -6440,7 +6434,7 @@ async fn join_channel_internal(
|
|||
// this loop will terminate within client::CONNECTION_TIMEOUT seconds.
|
||||
'outer: loop {
|
||||
let Some(status) = client_status.recv().await else {
|
||||
return Err(anyhow!("error connecting"));
|
||||
anyhow::bail!("error connecting");
|
||||
};
|
||||
|
||||
match status {
|
||||
|
@ -6662,7 +6656,7 @@ pub fn open_paths(
|
|||
) -> Task<
|
||||
anyhow::Result<(
|
||||
WindowHandle<Workspace>,
|
||||
Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>,
|
||||
Vec<Option<anyhow::Result<Box<dyn ItemHandle>>>>,
|
||||
)>,
|
||||
> {
|
||||
let abs_paths = abs_paths.to_vec();
|
||||
|
@ -6824,7 +6818,7 @@ pub fn create_and_open_local_file(
|
|||
.await;
|
||||
|
||||
let item = items.pop().flatten();
|
||||
item.ok_or_else(|| anyhow!("path {path:?} is not a file"))?
|
||||
item.with_context(|| format!("path {path:?} is not a file"))?
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -6945,9 +6939,7 @@ async fn open_ssh_project_inner(
|
|||
}
|
||||
|
||||
if project_paths_to_open.is_empty() {
|
||||
return Err(project_path_errors
|
||||
.pop()
|
||||
.unwrap_or_else(|| anyhow!("no paths given")));
|
||||
return Err(project_path_errors.pop().context("no paths given")?);
|
||||
}
|
||||
|
||||
cx.update_window(window.into(), |_, window, cx| {
|
||||
|
@ -7053,7 +7045,7 @@ pub fn join_in_room_project(
|
|||
let active_call = cx.update(|cx| ActiveCall::global(cx))?;
|
||||
let room = active_call
|
||||
.read_with(cx, |call, _| call.room().cloned())?
|
||||
.ok_or_else(|| anyhow!("not in a call"))?;
|
||||
.context("not in a call")?;
|
||||
let project = room
|
||||
.update(cx, |room, cx| {
|
||||
room.join_project(
|
||||
|
@ -9351,7 +9343,7 @@ mod tests {
|
|||
_project: &Entity<Project>,
|
||||
path: &ProjectPath,
|
||||
cx: &mut App,
|
||||
) -> Option<Task<gpui::Result<Entity<Self>>>> {
|
||||
) -> Option<Task<anyhow::Result<Entity<Self>>>> {
|
||||
if path.path.extension().unwrap() == "png" {
|
||||
Some(cx.spawn(async move |cx| cx.new(|_| TestPngItem {})))
|
||||
} else {
|
||||
|
@ -9426,7 +9418,7 @@ mod tests {
|
|||
_project: &Entity<Project>,
|
||||
path: &ProjectPath,
|
||||
cx: &mut App,
|
||||
) -> Option<Task<gpui::Result<Entity<Self>>>> {
|
||||
) -> Option<Task<anyhow::Result<Entity<Self>>>> {
|
||||
if path.path.extension().unwrap() == "ipynb" {
|
||||
Some(cx.spawn(async move |cx| cx.new(|_| TestIpynbItem {})))
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue