Files
bevy/_release-content/release-notes/bevy_error_context.md
Cookie 8bf04c642f Add context messages to BevyError (#24528)
# Objective

Add a `context()` extension method to `Result<T>` and `Option<T>` like
`anyhow`

## Solution

Add a `Vec<String>` field to `InnerBevyError` to store context messages
added via `context()`

Fixes #19714.

## Testing

Added the `context` unit test to test messages produced by `context() `
and a `context_downcasting` unit test to test that downcasting still
works when using `.context`

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2026-06-17 04:24:05 +00:00

1.4 KiB

title, authors, pull_requests
title authors pull_requests
Bevy Error Context Messages
@cookie1170
24528

Similar to the popular anyhow crate, BevyError now provides an ergonomic way to attach extra context to an error using the context method, which also allows creating a Result<T, BevyError> from an Option<T>.

This makes it easier to trace back errors with human-readable messages without looking at verbose backtraces.

fn fallible() -> Result<(), BevyError> {
    // This produces the error message `Failed to parse number: invalid digit found in string`
    let parsed: usize = "I am not a number"
        .parse()
        .context("Failed to parse number")?;

    Ok(())
}

with_context may be used to produce the error string with a closure instead.

If multiple contexts were used on the same BevyError, they're enumerated below:

fn fallible() -> Result<Package, BevyError> {
    let path = "package.json";
    let package = std::fs::read_to_string(path)
        .with_context(|| format!("Failed to read {path}"))?;

    serde_json::parse(&package)?
}

fn uses_fallible() -> Result<(), BevyError> {
    let package = fallible().context("Failed to parse package.json")?;
    // Use `package`...
}

Will produce the following error if package.json is missing:

Failed to parse package.json

Caused by:
    Failed to read package.json
    No such file or directory (os error 2)