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
|
@ -1204,7 +1204,7 @@ impl LocalLspStore {
|
|||
buffer.finalize_last_transaction();
|
||||
let transaction_id = buffer
|
||||
.start_transaction()
|
||||
.ok_or_else(|| anyhow!("transaction already open"))?;
|
||||
.context("transaction already open")?;
|
||||
let transaction = buffer
|
||||
.get_transaction(transaction_id)
|
||||
.expect("transaction started")
|
||||
|
@ -1862,14 +1862,14 @@ impl LocalLspStore {
|
|||
let capabilities = &language_server.capabilities();
|
||||
let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
|
||||
if range_formatting_provider.map_or(false, |provider| provider == &OneOf::Left(false)) {
|
||||
return Err(anyhow!(
|
||||
anyhow::bail!(
|
||||
"{} language server does not support range formatting",
|
||||
language_server.name()
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
let uri = lsp::Url::from_file_path(abs_path)
|
||||
.map_err(|_| anyhow!("failed to convert abs path to uri"))?;
|
||||
.map_err(|()| anyhow!("failed to convert abs path to uri"))?;
|
||||
let text_document = lsp::TextDocumentIdentifier::new(uri);
|
||||
|
||||
let lsp_edits = {
|
||||
|
@ -1934,7 +1934,7 @@ impl LocalLspStore {
|
|||
zlog::info!(logger => "Formatting via LSP");
|
||||
|
||||
let uri = lsp::Url::from_file_path(abs_path)
|
||||
.map_err(|_| anyhow!("failed to convert abs path to uri"))?;
|
||||
.map_err(|()| anyhow!("failed to convert abs path to uri"))?;
|
||||
let text_document = lsp::TextDocumentIdentifier::new(uri);
|
||||
let capabilities = &language_server.capabilities();
|
||||
|
||||
|
@ -2026,10 +2026,7 @@ impl LocalLspStore {
|
|||
.stderr(smol::process::Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
let stdin = child
|
||||
.stdin
|
||||
.as_mut()
|
||||
.ok_or_else(|| anyhow!("failed to acquire stdin"))?;
|
||||
let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
|
||||
let text = buffer
|
||||
.handle
|
||||
.update(cx, |buffer, _| buffer.as_rope().clone())?;
|
||||
|
@ -2039,14 +2036,13 @@ impl LocalLspStore {
|
|||
stdin.flush().await?;
|
||||
|
||||
let output = child.output().await?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!(
|
||||
"command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
|
||||
output.status.code(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
));
|
||||
}
|
||||
anyhow::ensure!(
|
||||
output.status.success(),
|
||||
"command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
|
||||
output.status.code(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
);
|
||||
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
Ok(Some(
|
||||
|
@ -2570,9 +2566,7 @@ impl LocalLspStore {
|
|||
// We detect this case and treat it as if the version was `None`.
|
||||
return Ok(buffer.read(cx).text_snapshot());
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"no snapshots found for buffer {buffer_id} and server {server_id}"
|
||||
));
|
||||
anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
|
||||
};
|
||||
|
||||
let found_snapshot = snapshots
|
||||
|
@ -2617,7 +2611,7 @@ impl LocalLspStore {
|
|||
push_to_history: bool,
|
||||
project_transaction: &mut ProjectTransaction,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
) -> anyhow::Result<()> {
|
||||
for mut action in actions {
|
||||
Self::try_resolve_code_action(language_server, &mut action)
|
||||
.await
|
||||
|
@ -2846,7 +2840,7 @@ impl LocalLspStore {
|
|||
let abs_path = op
|
||||
.uri
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow!("can't convert URI to path"))?;
|
||||
.map_err(|()| anyhow!("can't convert URI to path"))?;
|
||||
|
||||
if let Some(parent_path) = abs_path.parent() {
|
||||
fs.create_dir(parent_path).await?;
|
||||
|
@ -2871,11 +2865,11 @@ impl LocalLspStore {
|
|||
let source_abs_path = op
|
||||
.old_uri
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow!("can't convert URI to path"))?;
|
||||
.map_err(|()| anyhow!("can't convert URI to path"))?;
|
||||
let target_abs_path = op
|
||||
.new_uri
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow!("can't convert URI to path"))?;
|
||||
.map_err(|()| anyhow!("can't convert URI to path"))?;
|
||||
fs.rename(
|
||||
&source_abs_path,
|
||||
&target_abs_path,
|
||||
|
@ -2893,7 +2887,7 @@ impl LocalLspStore {
|
|||
let abs_path = op
|
||||
.uri
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow!("can't convert URI to path"))?;
|
||||
.map_err(|()| anyhow!("can't convert URI to path"))?;
|
||||
let options = op
|
||||
.options
|
||||
.map(|options| fs::RemoveOptions {
|
||||
|
@ -3042,12 +3036,10 @@ impl LocalLspStore {
|
|||
adapter: Arc<CachedLspAdapter>,
|
||||
cx: &mut AsyncApp,
|
||||
) -> Result<lsp::ApplyWorkspaceEditResponse> {
|
||||
let this = this
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("project project closed"))?;
|
||||
let this = this.upgrade().context("project project closed")?;
|
||||
let language_server = this
|
||||
.update(cx, |this, _| this.language_server_for_id(server_id))?
|
||||
.ok_or_else(|| anyhow!("language server not found"))?;
|
||||
.context("language server not found")?;
|
||||
let transaction = Self::deserialize_workspace_edit(
|
||||
this.clone(),
|
||||
params.edit,
|
||||
|
@ -4372,13 +4364,13 @@ impl LspStore {
|
|||
err
|
||||
);
|
||||
log::warn!("{message}");
|
||||
anyhow!(message)
|
||||
anyhow::anyhow!(message)
|
||||
})?;
|
||||
|
||||
let response = request
|
||||
.response_from_lsp(
|
||||
response,
|
||||
this.upgrade().ok_or_else(|| anyhow!("no app context"))?,
|
||||
this.upgrade().context("no app context")?,
|
||||
buffer_handle,
|
||||
language_server.server_id(),
|
||||
cx.clone(),
|
||||
|
@ -4591,7 +4583,7 @@ impl LspStore {
|
|||
.request(request)
|
||||
.await?
|
||||
.transaction
|
||||
.ok_or_else(|| anyhow!("missing transaction"))?;
|
||||
.context("missing transaction")?;
|
||||
|
||||
buffer_store
|
||||
.update(cx, |buffer_store, cx| {
|
||||
|
@ -4613,7 +4605,7 @@ impl LspStore {
|
|||
if let Some(edit) = action.lsp_action.edit() {
|
||||
if edit.changes.is_some() || edit.document_changes.is_some() {
|
||||
return LocalLspStore::deserialize_workspace_edit(
|
||||
this.upgrade().ok_or_else(|| anyhow!("no app present"))?,
|
||||
this.upgrade().context("no app present")?,
|
||||
edit.clone(),
|
||||
push_to_history,
|
||||
lsp_adapter.clone(),
|
||||
|
@ -5715,7 +5707,7 @@ impl LspStore {
|
|||
LspCommand::response_from_proto(
|
||||
lsp_request,
|
||||
response,
|
||||
project.upgrade().ok_or_else(|| anyhow!("No project"))?,
|
||||
project.upgrade().context("No project")?,
|
||||
buffer_handle.clone(),
|
||||
cx.clone(),
|
||||
)
|
||||
|
@ -6525,7 +6517,7 @@ impl LspStore {
|
|||
mut diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
|
||||
filter: F,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
) -> anyhow::Result<()> {
|
||||
let Some((worktree, relative_path)) =
|
||||
self.worktree_store.read(cx).find_worktree(&abs_path, cx)
|
||||
else {
|
||||
|
@ -6730,7 +6722,7 @@ impl LspStore {
|
|||
|
||||
let abs_path = abs_path
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow!("can't convert URI to path"))?;
|
||||
.map_err(|()| anyhow!("can't convert URI to path"))?;
|
||||
let p = abs_path.clone();
|
||||
let yarn_worktree = lsp_store
|
||||
.update(cx, move |lsp_store, cx| match lsp_store.as_local() {
|
||||
|
@ -7094,12 +7086,8 @@ impl LspStore {
|
|||
mut cx: AsyncApp,
|
||||
) -> Result<proto::ApplyCodeActionResponse> {
|
||||
let sender_id = envelope.original_sender_id().unwrap_or_default();
|
||||
let action = Self::deserialize_code_action(
|
||||
envelope
|
||||
.payload
|
||||
.action
|
||||
.ok_or_else(|| anyhow!("invalid action"))?,
|
||||
)?;
|
||||
let action =
|
||||
Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
|
||||
let apply_code_action = this.update(&mut cx, |this, cx| {
|
||||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
|
||||
|
@ -7198,7 +7186,7 @@ impl LspStore {
|
|||
)
|
||||
})
|
||||
})?
|
||||
.ok_or_else(|| anyhow!("worktree not found"))?;
|
||||
.context("worktree not found")?;
|
||||
let (old_abs_path, new_abs_path) = {
|
||||
let root_path = worktree.update(&mut cx, |this, _| this.abs_path())?;
|
||||
let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
|
||||
|
@ -7288,10 +7276,7 @@ impl LspStore {
|
|||
envelope: TypedEnvelope<proto::StartLanguageServer>,
|
||||
mut cx: AsyncApp,
|
||||
) -> Result<()> {
|
||||
let server = envelope
|
||||
.payload
|
||||
.server
|
||||
.ok_or_else(|| anyhow!("invalid server"))?;
|
||||
let server = envelope.payload.server.context("invalid server")?;
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let server_id = LanguageServerId(server.id as usize);
|
||||
|
@ -7322,11 +7307,7 @@ impl LspStore {
|
|||
this.update(&mut cx, |this, cx| {
|
||||
let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
|
||||
|
||||
match envelope
|
||||
.payload
|
||||
.variant
|
||||
.ok_or_else(|| anyhow!("invalid variant"))?
|
||||
{
|
||||
match envelope.payload.variant.context("invalid variant")? {
|
||||
proto::update_language_server::Variant::WorkStart(payload) => {
|
||||
this.on_lsp_work_start(
|
||||
language_server_id,
|
||||
|
@ -7903,11 +7884,11 @@ impl LspStore {
|
|||
let completion = this
|
||||
.read_with(&cx, |this, cx| {
|
||||
let id = LanguageServerId(envelope.payload.language_server_id as usize);
|
||||
let Some(server) = this.language_server_for_id(id) else {
|
||||
return Err(anyhow!("No language server {id}"));
|
||||
};
|
||||
let server = this
|
||||
.language_server_for_id(id)
|
||||
.with_context(|| format!("No language server {id}"))?;
|
||||
|
||||
Ok(cx.background_spawn(async move {
|
||||
anyhow::Ok(cx.background_spawn(async move {
|
||||
let can_resolve = server
|
||||
.capabilities()
|
||||
.completion_provider
|
||||
|
@ -7994,8 +7975,8 @@ impl LspStore {
|
|||
.payload
|
||||
.position
|
||||
.and_then(deserialize_anchor)
|
||||
.ok_or_else(|| anyhow!("invalid position"))?;
|
||||
Ok::<_, anyhow::Error>(this.apply_on_type_formatting(
|
||||
.context("invalid position")?;
|
||||
anyhow::Ok(this.apply_on_type_formatting(
|
||||
buffer,
|
||||
position,
|
||||
envelope.payload.trigger.clone(),
|
||||
|
@ -8114,18 +8095,12 @@ impl LspStore {
|
|||
mut cx: AsyncApp,
|
||||
) -> Result<proto::OpenBufferForSymbolResponse> {
|
||||
let peer_id = envelope.original_sender_id().unwrap_or_default();
|
||||
let symbol = envelope
|
||||
.payload
|
||||
.symbol
|
||||
.ok_or_else(|| anyhow!("invalid symbol"))?;
|
||||
let symbol = envelope.payload.symbol.context("invalid symbol")?;
|
||||
let symbol = Self::deserialize_symbol(symbol)?;
|
||||
let symbol = this.update(&mut cx, |this, _| {
|
||||
let signature = this.symbol_signature(&symbol.path);
|
||||
if signature == symbol.signature {
|
||||
Ok(symbol)
|
||||
} else {
|
||||
Err(anyhow!("invalid symbol signature"))
|
||||
}
|
||||
anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
|
||||
Ok(symbol)
|
||||
})??;
|
||||
let buffer = this
|
||||
.update(&mut cx, |this, cx| {
|
||||
|
@ -8268,10 +8243,7 @@ impl LspStore {
|
|||
let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
|
||||
let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
|
||||
let completion = Self::deserialize_completion(
|
||||
envelope
|
||||
.payload
|
||||
.completion
|
||||
.ok_or_else(|| anyhow!("invalid completion"))?,
|
||||
envelope.payload.completion.context("invalid completion")?,
|
||||
)?;
|
||||
anyhow::Ok((buffer, completion))
|
||||
})??;
|
||||
|
@ -8365,10 +8337,7 @@ impl LspStore {
|
|||
let ranges = match &target {
|
||||
LspFormatTarget::Buffers => None,
|
||||
LspFormatTarget::Ranges(ranges) => {
|
||||
let Some(ranges) = ranges.get(&id) else {
|
||||
return Err(anyhow!("No format ranges provided for buffer"));
|
||||
};
|
||||
Some(ranges.clone())
|
||||
Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8498,17 +8467,20 @@ impl LspStore {
|
|||
buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
|
||||
}
|
||||
let kind = match envelope.payload.kind.as_str() {
|
||||
"" => Ok(CodeActionKind::EMPTY),
|
||||
"quickfix" => Ok(CodeActionKind::QUICKFIX),
|
||||
"refactor" => Ok(CodeActionKind::REFACTOR),
|
||||
"refactor.extract" => Ok(CodeActionKind::REFACTOR_EXTRACT),
|
||||
"refactor.inline" => Ok(CodeActionKind::REFACTOR_INLINE),
|
||||
"refactor.rewrite" => Ok(CodeActionKind::REFACTOR_REWRITE),
|
||||
"source" => Ok(CodeActionKind::SOURCE),
|
||||
"source.organizeImports" => Ok(CodeActionKind::SOURCE_ORGANIZE_IMPORTS),
|
||||
"source.fixAll" => Ok(CodeActionKind::SOURCE_FIX_ALL),
|
||||
_ => Err(anyhow!("Invalid code action kind")),
|
||||
}?;
|
||||
"" => CodeActionKind::EMPTY,
|
||||
"quickfix" => CodeActionKind::QUICKFIX,
|
||||
"refactor" => CodeActionKind::REFACTOR,
|
||||
"refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
|
||||
"refactor.inline" => CodeActionKind::REFACTOR_INLINE,
|
||||
"refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
|
||||
"source" => CodeActionKind::SOURCE,
|
||||
"source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
|
||||
"source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
|
||||
_ => anyhow::bail!(
|
||||
"Invalid code action kind {}",
|
||||
envelope.payload.kind.as_str()
|
||||
),
|
||||
};
|
||||
anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
|
||||
})??;
|
||||
|
||||
|
@ -8778,7 +8750,7 @@ impl LspStore {
|
|||
let abs_path = params
|
||||
.uri
|
||||
.to_file_path()
|
||||
.map_err(|_| anyhow!("URI is not a file"))?;
|
||||
.map_err(|()| anyhow!("URI is not a file"))?;
|
||||
let mut diagnostics = Vec::default();
|
||||
let mut primary_diagnostic_group_ids = HashMap::default();
|
||||
let mut sources_by_group_id = HashMap::default();
|
||||
|
@ -9320,12 +9292,8 @@ impl LspStore {
|
|||
path: Arc::<Path>::from_proto(serialized_symbol.path),
|
||||
};
|
||||
|
||||
let start = serialized_symbol
|
||||
.start
|
||||
.ok_or_else(|| anyhow!("invalid start"))?;
|
||||
let end = serialized_symbol
|
||||
.end
|
||||
.ok_or_else(|| anyhow!("invalid end"))?;
|
||||
let start = serialized_symbol.start.context("invalid start")?;
|
||||
let end = serialized_symbol.end.context("invalid end")?;
|
||||
Ok(CoreSymbol {
|
||||
language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
|
||||
source_worktree_id,
|
||||
|
@ -10307,15 +10275,14 @@ impl LspAdapterDelegate for LocalLspAdapterDelegate {
|
|||
.output()
|
||||
.await?;
|
||||
|
||||
if output.status.success() {
|
||||
return Ok(());
|
||||
}
|
||||
Err(anyhow!(
|
||||
anyhow::ensure!(
|
||||
output.status.success(),
|
||||
"{}, stdout: {:?}, stderr: {:?}",
|
||||
output.status,
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
))
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue