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:
Kirill Bulatov 2025-05-21 02:06:07 +03:00 committed by GitHub
parent 1e51a7ac44
commit 16366cf9f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
294 changed files with 2037 additions and 2610 deletions

View file

@ -2022,7 +2022,7 @@ impl Project {
worktree.expand_all_for_entry(entry_id, cx)
});
Some(cx.spawn(async move |this, cx| {
task.ok_or_else(|| anyhow!("no task"))?.await?;
task.context("no task")?.await?;
this.update(cx, |_, cx| {
cx.emit(Event::ExpandedAllForEntry(worktree_id, entry_id));
})?;
@ -2031,9 +2031,10 @@ impl Project {
}
pub fn shared(&mut self, project_id: u64, cx: &mut Context<Self>) -> Result<()> {
if !matches!(self.client_state, ProjectClientState::Local) {
return Err(anyhow!("project was already shared"));
}
anyhow::ensure!(
matches!(self.client_state, ProjectClientState::Local),
"project was already shared"
);
self.client_subscriptions.extend([
self.client
@ -2151,9 +2152,10 @@ impl Project {
}
fn unshare_internal(&mut self, cx: &mut App) -> Result<()> {
if self.is_via_collab() {
return Err(anyhow!("attempted to unshare a remote project"));
}
anyhow::ensure!(
!self.is_via_collab(),
"attempted to unshare a remote project"
);
if let ProjectClientState::Shared { remote_id, .. } = self.client_state {
self.client_state = ProjectClientState::Local;
@ -2189,7 +2191,7 @@ impl Project {
.ok();
Ok(())
} else {
Err(anyhow!("attempted to unshare an unshared project"))
anyhow::bail!("attempted to unshare an unshared project");
}
}
@ -2431,7 +2433,7 @@ impl Project {
if let Some(buffer) = self.buffer_for_id(id, cx) {
Task::ready(Ok(buffer))
} else if self.is_local() || self.is_via_ssh() {
Task::ready(Err(anyhow!("buffer {} does not exist", id)))
Task::ready(Err(anyhow!("buffer {id} does not exist")))
} else if let Some(project_id) = self.remote_id() {
let request = self.client.request(proto::OpenBufferById {
project_id,
@ -2521,9 +2523,7 @@ impl Project {
let weak_project = cx.entity().downgrade();
cx.spawn(async move |_, cx| {
let image_item = open_image_task.await?;
let project = weak_project
.upgrade()
.ok_or_else(|| anyhow!("Project dropped"))?;
let project = weak_project.upgrade().context("Project dropped")?;
let metadata = ImageItem::load_image_metadata(image_item.clone(), project, cx).await?;
image_item.update(cx, |image_item, cx| {
@ -4272,7 +4272,7 @@ impl Project {
.payload
.collaborator
.take()
.ok_or_else(|| anyhow!("empty collaborator"))?;
.context("empty collaborator")?;
let collaborator = Collaborator::from_proto(collaborator)?;
this.update(&mut cx, |this, cx| {
@ -4296,16 +4296,16 @@ impl Project {
let old_peer_id = envelope
.payload
.old_peer_id
.ok_or_else(|| anyhow!("missing old peer id"))?;
.context("missing old peer id")?;
let new_peer_id = envelope
.payload
.new_peer_id
.ok_or_else(|| anyhow!("missing new peer id"))?;
.context("missing new peer id")?;
this.update(&mut cx, |this, cx| {
let collaborator = this
.collaborators
.remove(&old_peer_id)
.ok_or_else(|| anyhow!("received UpdateProjectCollaborator for unknown peer"))?;
.context("received UpdateProjectCollaborator for unknown peer")?;
let is_host = collaborator.is_host;
this.collaborators.insert(new_peer_id, collaborator);
@ -4336,14 +4336,11 @@ impl Project {
mut cx: AsyncApp,
) -> Result<()> {
this.update(&mut cx, |this, cx| {
let peer_id = envelope
.payload
.peer_id
.ok_or_else(|| anyhow!("invalid peer id"))?;
let peer_id = envelope.payload.peer_id.context("invalid peer id")?;
let replica_id = this
.collaborators
.remove(&peer_id)
.ok_or_else(|| anyhow!("unknown peer {:?}", peer_id))?
.with_context(|| format!("unknown peer {peer_id:?}"))?
.replica_id;
this.buffer_store.update(cx, |buffer_store, cx| {
buffer_store.forget_shared_buffers_for(&peer_id);
@ -4557,11 +4554,7 @@ impl Project {
) -> Result<proto::FindSearchCandidatesResponse> {
let peer_id = envelope.original_sender_id()?;
let message = envelope.payload;
let query = SearchQuery::from_proto(
message
.query
.ok_or_else(|| anyhow!("missing query field"))?,
)?;
let query = SearchQuery::from_proto(message.query.context("missing query field")?)?;
let results = this.update(&mut cx, |this, cx| {
this.find_search_candidate_buffers(&query, message.limit as _, cx)
})?;
@ -4639,13 +4632,10 @@ impl Project {
.file()
.map(|f| f.is_private())
.unwrap_or_default();
if is_private {
Err(anyhow!(ErrorCode::UnsharedItem))
} else {
Ok(proto::OpenBufferResponse {
buffer_id: this.create_buffer_for_peer(&buffer, peer_id, cx).into(),
})
}
anyhow::ensure!(!is_private, ErrorCode::UnsharedItem);
Ok(proto::OpenBufferResponse {
buffer_id: this.create_buffer_for_peer(&buffer, peer_id, cx).into(),
})
})?
}