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:
@@ -30,7 +30,7 @@ impl BladeContext {
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.map_err(|e| anyhow::anyhow!("{:?}", e))?,
|
||||
.map_err(|e| anyhow::anyhow!("{e:?}"))?,
|
||||
);
|
||||
Ok(Self { gpu })
|
||||
}
|
||||
@@ -49,8 +49,7 @@ fn parse_pci_id(id: &str) -> anyhow::Result<u32> {
|
||||
"Expected a 4 digit PCI ID in hexadecimal format"
|
||||
);
|
||||
|
||||
return u32::from_str_radix(id, 16)
|
||||
.map_err(|_| anyhow::anyhow!("Failed to parse PCI ID as hex"));
|
||||
return u32::from_str_radix(id, 16).context("parsing PCI ID as hex");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -95,9 +95,7 @@ impl LinuxClient for HeadlessClient {
|
||||
_handle: AnyWindowHandle,
|
||||
_params: WindowParams,
|
||||
) -> anyhow::Result<Box<dyn PlatformWindow>> {
|
||||
Err(anyhow::anyhow!(
|
||||
"neither DISPLAY nor WAYLAND_DISPLAY is set. You can run in headless mode"
|
||||
))
|
||||
anyhow::bail!("neither DISPLAY nor WAYLAND_DISPLAY is set. You can run in headless mode");
|
||||
}
|
||||
|
||||
fn compositor_name(&self) -> &'static str {
|
||||
|
||||
@@ -490,7 +490,7 @@ impl<P: LinuxClient + 'static> Platform for P {
|
||||
let attributes = item.attributes().await?;
|
||||
let username = attributes
|
||||
.get("username")
|
||||
.ok_or_else(|| anyhow!("Cannot find username in stored credentials"))?;
|
||||
.context("Cannot find username in stored credentials")?;
|
||||
let secret = item.secret().await?;
|
||||
|
||||
// we lose the zeroizing capabilities at this boundary,
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, RenderGlyphParams, SUBPIXEL_VARIANTS,
|
||||
ShapedGlyph, ShapedRun, SharedString, Size, point, size,
|
||||
};
|
||||
use anyhow::{Context as _, Ok, Result, anyhow};
|
||||
use anyhow::{Context as _, Ok, Result};
|
||||
use collections::HashMap;
|
||||
use cosmic_text::{
|
||||
Attrs, AttrsList, CacheKey, Family, Font as CosmicTextFont, FontFeatures as CosmicFontFeatures,
|
||||
@@ -232,7 +232,7 @@ impl CosmicTextSystemState {
|
||||
let font = self
|
||||
.font_system
|
||||
.get_font(font_id)
|
||||
.ok_or_else(|| anyhow!("Could not load font"))?;
|
||||
.context("Could not load font")?;
|
||||
|
||||
// HACK: To let the storybook run and render Windows caption icons. We should actually do better font fallback.
|
||||
let allowed_bad_font_names = [
|
||||
@@ -309,7 +309,7 @@ impl CosmicTextSystemState {
|
||||
glyph_bounds: Bounds<DevicePixels>,
|
||||
) -> Result<(Size<DevicePixels>, Vec<u8>)> {
|
||||
if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 {
|
||||
Err(anyhow!("glyph bounds are empty"))
|
||||
anyhow::bail!("glyph bounds are empty");
|
||||
} else {
|
||||
let bitmap_size = glyph_bounds.size;
|
||||
let font = &self.loaded_fonts[params.font_id.0].font;
|
||||
@@ -469,7 +469,7 @@ impl TryFrom<&FontFeatures> for CosmicFontFeatures {
|
||||
.0
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.map_err(|_| anyhow!("Incorrect feature flag format"))?;
|
||||
.context("Incorrect feature flag format")?;
|
||||
|
||||
let tag = cosmic_text::FeatureTag::new(&name_bytes);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::{
|
||||
hash::{Hash, Hasher},
|
||||
};
|
||||
|
||||
use anyhow::Context as _;
|
||||
use uuid::Uuid;
|
||||
use wayland_backend::client::ObjectId;
|
||||
|
||||
@@ -28,11 +29,11 @@ impl PlatformDisplay for WaylandDisplay {
|
||||
}
|
||||
|
||||
fn uuid(&self) -> anyhow::Result<Uuid> {
|
||||
if let Some(name) = &self.name {
|
||||
Ok(Uuid::new_v5(&Uuid::NAMESPACE_DNS, name.as_bytes()))
|
||||
} else {
|
||||
Err(anyhow::anyhow!("Wayland display does not have a name"))
|
||||
}
|
||||
let name = self
|
||||
.name
|
||||
.as_ref()
|
||||
.context("Wayland display does not have a name")?;
|
||||
Ok(Uuid::new_v5(&Uuid::NAMESPACE_DNS, name.as_bytes()))
|
||||
}
|
||||
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anyhow::Result;
|
||||
use anyhow::Context as _;
|
||||
use uuid::Uuid;
|
||||
use x11rb::{connection::Connection as _, xcb_ffi::XCBConnection};
|
||||
|
||||
@@ -17,12 +17,11 @@ impl X11Display {
|
||||
scale_factor: f32,
|
||||
x_screen_index: usize,
|
||||
) -> anyhow::Result<Self> {
|
||||
let Some(screen) = xcb.setup().roots.get(x_screen_index) else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"No screen found with index {}",
|
||||
x_screen_index
|
||||
));
|
||||
};
|
||||
let screen = xcb
|
||||
.setup()
|
||||
.roots
|
||||
.get(x_screen_index)
|
||||
.with_context(|| format!("No screen found with index {x_screen_index}"))?;
|
||||
Ok(Self {
|
||||
x_screen_index,
|
||||
bounds: Bounds {
|
||||
@@ -42,7 +41,7 @@ impl PlatformDisplay for X11Display {
|
||||
DisplayId(self.x_screen_index as u32)
|
||||
}
|
||||
|
||||
fn uuid(&self) -> Result<Uuid> {
|
||||
fn uuid(&self) -> anyhow::Result<Uuid> {
|
||||
Ok(self.uuid)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
AtlasKey, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, DevicePixels, PlatformAtlas,
|
||||
Point, Size, platform::AtlasTextureList,
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use collections::FxHashMap;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use etagere::BucketedAtlasAllocator;
|
||||
@@ -77,7 +77,7 @@ impl PlatformAtlas for MetalAtlas {
|
||||
};
|
||||
let tile = lock
|
||||
.allocate(size, key.texture_kind())
|
||||
.ok_or_else(|| anyhow!("failed to allocate"))?;
|
||||
.context("failed to allocate")?;
|
||||
let texture = lock.texture(tile.texture_id);
|
||||
texture.upload(tile.bounds, &bytes);
|
||||
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
MonochromeSprite, PaintSurface, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch,
|
||||
Quad, ScaledPixels, Scene, Shadow, Size, Surface, Underline, point, size,
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use block::ConcreteBlock;
|
||||
use cocoa::{
|
||||
base::{NO, YES},
|
||||
@@ -376,14 +376,14 @@ impl MetalRenderer {
|
||||
let command_buffer = command_queue.new_command_buffer();
|
||||
let mut instance_offset = 0;
|
||||
|
||||
let Some(path_tiles) = self.rasterize_paths(
|
||||
scene.paths(),
|
||||
instance_buffer,
|
||||
&mut instance_offset,
|
||||
command_buffer,
|
||||
) else {
|
||||
return Err(anyhow!("failed to rasterize {} paths", scene.paths().len()));
|
||||
};
|
||||
let path_tiles = self
|
||||
.rasterize_paths(
|
||||
scene.paths(),
|
||||
instance_buffer,
|
||||
&mut instance_offset,
|
||||
command_buffer,
|
||||
)
|
||||
.with_context(|| format!("rasterizing {} paths", scene.paths().len()))?;
|
||||
|
||||
let render_pass_descriptor = metal::RenderPassDescriptor::new();
|
||||
let color_attachment = render_pass_descriptor
|
||||
@@ -471,7 +471,7 @@ impl MetalRenderer {
|
||||
|
||||
if !ok {
|
||||
command_encoder.end_encoding();
|
||||
return Err(anyhow!(
|
||||
anyhow::bail!(
|
||||
"scene too large: {} paths, {} shadows, {} quads, {} underlines, {} mono, {} poly, {} surfaces",
|
||||
scene.paths.len(),
|
||||
scene.shadows.len(),
|
||||
@@ -480,7 +480,7 @@ impl MetalRenderer {
|
||||
scene.monochrome_sprites.len(),
|
||||
scene.polychrome_sprites.len(),
|
||||
scene.surfaces.len(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -638,7 +638,7 @@ impl Platform for MacPlatform {
|
||||
Ok(())
|
||||
} else {
|
||||
let msg: id = msg_send![error, localizedDescription];
|
||||
Err(anyhow!("Failed to register: {:?}", msg))
|
||||
Err(anyhow!("Failed to register: {msg:?}"))
|
||||
};
|
||||
|
||||
if let Some(done_tx) = done_tx.take() {
|
||||
@@ -832,11 +832,8 @@ impl Platform for MacPlatform {
|
||||
fn app_path(&self) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
Ok(path_from_objc(msg_send![bundle, bundlePath]))
|
||||
}
|
||||
anyhow::ensure!(!bundle.is_null(), "app is not running inside a bundle");
|
||||
Ok(path_from_objc(msg_send![bundle, bundlePath]))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,17 +874,11 @@ impl Platform for MacPlatform {
|
||||
fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
if url.is_null() {
|
||||
Err(anyhow!("resource not found"))
|
||||
} else {
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
anyhow::ensure!(!bundle.is_null(), "app is not running inside a bundle");
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
anyhow::ensure!(!url.is_null(), "resource not found");
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1101,10 +1092,7 @@ impl Platform for MacPlatform {
|
||||
verb = "creating";
|
||||
status = SecItemAdd(attrs.as_concrete_TypeRef(), ptr::null_mut());
|
||||
}
|
||||
|
||||
if status != errSecSuccess {
|
||||
return Err(anyhow!("{} password failed: {}", verb, status));
|
||||
}
|
||||
anyhow::ensure!(status == errSecSuccess, "{verb} password failed: {status}");
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
@@ -1131,24 +1119,24 @@ impl Platform for MacPlatform {
|
||||
match status {
|
||||
security::errSecSuccess => {}
|
||||
security::errSecItemNotFound | security::errSecUserCanceled => return Ok(None),
|
||||
_ => return Err(anyhow!("reading password failed: {}", status)),
|
||||
_ => anyhow::bail!("reading password failed: {status}"),
|
||||
}
|
||||
|
||||
let result = CFType::wrap_under_create_rule(result)
|
||||
.downcast::<CFDictionary>()
|
||||
.ok_or_else(|| anyhow!("keychain item was not a dictionary"))?;
|
||||
.context("keychain item was not a dictionary")?;
|
||||
let username = result
|
||||
.find(kSecAttrAccount as *const _)
|
||||
.ok_or_else(|| anyhow!("account was missing from keychain item"))?;
|
||||
.context("account was missing from keychain item")?;
|
||||
let username = CFType::wrap_under_get_rule(*username)
|
||||
.downcast::<CFString>()
|
||||
.ok_or_else(|| anyhow!("account was not a string"))?;
|
||||
.context("account was not a string")?;
|
||||
let password = result
|
||||
.find(kSecValueData as *const _)
|
||||
.ok_or_else(|| anyhow!("password was missing from keychain item"))?;
|
||||
.context("password was missing from keychain item")?;
|
||||
let password = CFType::wrap_under_get_rule(*password)
|
||||
.downcast::<CFData>()
|
||||
.ok_or_else(|| anyhow!("password was not a string"))?;
|
||||
.context("password was not a string")?;
|
||||
|
||||
Ok(Some((username.to_string(), password.bytes().to_vec())))
|
||||
}
|
||||
@@ -1168,10 +1156,7 @@ impl Platform for MacPlatform {
|
||||
query_attrs.set(kSecAttrServer as *const _, url.as_CFTypeRef());
|
||||
|
||||
let status = SecItemDelete(query_attrs.as_concrete_TypeRef());
|
||||
|
||||
if status != errSecSuccess {
|
||||
return Err(anyhow!("delete password failed: {}", status));
|
||||
}
|
||||
anyhow::ensure!(status == errSecSuccess, "delete password failed: {status}");
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
@@ -1455,15 +1440,12 @@ unsafe fn ns_string(string: &str) -> id {
|
||||
|
||||
unsafe fn ns_url_to_path(url: id) -> Result<PathBuf> {
|
||||
let path: *mut c_char = msg_send![url, fileSystemRepresentation];
|
||||
if path.is_null() {
|
||||
Err(anyhow!("url is not a file path: {}", unsafe {
|
||||
CStr::from_ptr(url.absoluteString().UTF8String()).to_string_lossy()
|
||||
}))
|
||||
} else {
|
||||
Ok(PathBuf::from(OsStr::from_bytes(unsafe {
|
||||
CStr::from_ptr(path).to_bytes()
|
||||
})))
|
||||
}
|
||||
anyhow::ensure!(!path.is_null(), "url is not a file path: {}", unsafe {
|
||||
CStr::from_ptr(url.absoluteString().UTF8String()).to_string_lossy()
|
||||
});
|
||||
Ok(PathBuf::from(OsStr::from_bytes(unsafe {
|
||||
CStr::from_ptr(path).to_bytes()
|
||||
})))
|
||||
}
|
||||
|
||||
#[link(name = "Carbon", kind = "framework")]
|
||||
|
||||
@@ -194,7 +194,7 @@ impl MacTextSystemState {
|
||||
core_graphics::data_provider::CGDataProvider::from_slice(embedded_font)
|
||||
};
|
||||
let font = core_graphics::font::CGFont::from_data_provider(data_provider)
|
||||
.map_err(|_| anyhow!("Could not load an embedded font."))?;
|
||||
.map_err(|()| anyhow!("Could not load an embedded font."))?;
|
||||
let font = font_kit::loaders::core_text::Font::from_core_graphics_font(font);
|
||||
Ok(Handle::from_native(&font))
|
||||
}
|
||||
@@ -348,7 +348,7 @@ impl MacTextSystemState {
|
||||
glyph_bounds: Bounds<DevicePixels>,
|
||||
) -> Result<(Size<DevicePixels>, Vec<u8>)> {
|
||||
if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 {
|
||||
Err(anyhow!("glyph bounds are empty"))
|
||||
anyhow::bail!("glyph bounds are empty");
|
||||
} else {
|
||||
// Add an extra pixel when the subpixel variant isn't zero to make room for anti-aliasing.
|
||||
let mut bitmap_size = glyph_bounds.size;
|
||||
|
||||
@@ -54,9 +54,7 @@ impl DockMenuItem {
|
||||
},
|
||||
action,
|
||||
}),
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"Only `MenuItem::Action` is supported for dock menu on Windows."
|
||||
)),
|
||||
_ => anyhow::bail!("Only `MenuItem::Action` is supported for dock menu on Windows."),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
use ::util::ResultExt;
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::Result;
|
||||
use collections::HashMap;
|
||||
use itertools::Itertools;
|
||||
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
|
||||
@@ -729,7 +729,7 @@ impl DirectWriteState {
|
||||
glyph_bounds: Bounds<DevicePixels>,
|
||||
) -> Result<(Size<DevicePixels>, Vec<u8>)> {
|
||||
if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 {
|
||||
return Err(anyhow!("glyph bounds are empty"));
|
||||
anyhow::bail!("glyph bounds are empty");
|
||||
}
|
||||
|
||||
let font_info = &self.fonts[params.font_id.0];
|
||||
@@ -1301,7 +1301,7 @@ fn get_postscript_name(font_face: &IDWriteFontFace3, locale: &str) -> Result<Str
|
||||
)?
|
||||
};
|
||||
if !exists.as_bool() || info.is_none() {
|
||||
return Err(anyhow!("No postscript name found for font face"));
|
||||
anyhow::bail!("No postscript name found for font face");
|
||||
}
|
||||
|
||||
get_name(info.unwrap(), locale)
|
||||
@@ -1393,9 +1393,7 @@ fn get_name(string: IDWriteLocalizedStrings, locale: &str) -> Result<String> {
|
||||
&mut exists as _,
|
||||
)?
|
||||
};
|
||||
if !exists.as_bool() {
|
||||
return Err(anyhow!("No localised string for {}", locale));
|
||||
}
|
||||
anyhow::ensure!(exists.as_bool(), "No localised string for {locale}");
|
||||
}
|
||||
|
||||
let name_length = unsafe { string.GetStringLength(locale_name_index) }? as usize;
|
||||
|
||||
@@ -576,7 +576,7 @@ impl Platform for WindowsPlatform {
|
||||
|
||||
// todo(windows)
|
||||
fn path_for_auxiliary_executable(&self, _name: &str) -> Result<PathBuf> {
|
||||
Err(anyhow!("not yet implemented"))
|
||||
anyhow::bail!("not yet implemented");
|
||||
}
|
||||
|
||||
fn set_cursor_style(&self, style: CursorStyle) {
|
||||
|
||||
Reference in New Issue
Block a user