Skip to main content

bail

Macro bail 

Source
macro_rules! bail {
    ($fmt:literal $(.$method:ident($($method_arg:tt)*))+ $(, $($arg:tt)*)?) => { ... };
    ($fmt:literal $(,)?) => { ... };
    (($err:expr) $(,)?) => { ... };
    ($err:expr $(,)?) => { ... };
    ($fmt:expr, $($arg:tt)*) => { ... };
}
Expand description

Creates an Exn and converts it to the function’s result error type.

Shorthand for return Err(Exn::from(err).into()). Works with both crate::Result and typed crate::ExnResult. Prefer to import the macro with use gix_error::bail; (or use gix::error::bail; in applications) and invoke it as bail!(...) instead of using a qualified path for readability.

String literals and format arguments implicitly construct a formatted Message, including captured arguments like bail!("invalid input: {input}"). Like message!, this always formats the message; use message() inside bail! for a static message without formatting. A string literal can be followed by method calls on the formatted Message, such as bail!("invalid record at {offset}".corrupted().with("offset", offset)). Explicit format arguments follow the method chain: bail!("invalid record at {}".corrupted(), offset). These methods apply to the message after formatting, not to the string literal itself. Parenthesize an ordinary error expression starting with a literal to avoid this shorthand, for example bail!(("bad".parse::<u32>().expect_err("invalid number"))). Without a classification builder, the shorthand leaves the error unclassified. Classified constructors also work, such as bail!(gix_error::validation("invalid input")).

§Examples

Create an Exn from Error:

use std::fs;

use gix_error::{bail, ExnResult};
match fs::read_to_string("/path/to/file") {
    Ok(content) => println!("file contents: {content}"),
    Err(err) => bail!(err),
}
use gix_error::{bail, Result};

fn public_api() -> Result {
    bail!(gix_error::validation("invalid input"));
}
assert!(public_api().expect_err("the input is invalid").is_validation());

Return a formatted message with captured or explicit arguments:

use gix_error::{bail, ExnMessageResult, Result};

fn captured(name: &str) -> Result {
    bail!("unknown executable '{name}'");
}

fn explicit(name: &str) -> ExnMessageResult {
    bail!("unknown executable '{}'", name);
}

Chain classification and metadata builders on a formatted message:

use std::path::Path;
use gix_error::{bail, ExnMessageResult, MetadataValue, Result};

fn captured(path: &Path) -> Result {
    bail!("Missing reference".not_found().with("path", path));
}

fn explicit(path: &Path) -> ExnMessageResult {
    bail!("Missing reference at '{}'".not_found().with("path", path), path.display());
}

let path = Path::new("refs/heads/main");
let error = captured(path).expect_err("the reference is missing");
assert!(error.is_not_found());
assert_eq!(error.metadata().next().expect("reference details")["path"], MetadataValue::Path(path.into()));
let error = explicit(path).expect_err("the reference is missing");
assert_eq!(error.error().message, "Missing reference at 'refs/heads/main'");
assert!(error.is_not_found());