# Hands-on Rust: How do I debug a call chain in Rust?

**URL:** <https://forum.devtalk.com/t/hands-on-rust-how-do-i-debug-a-call-chain-in-rust/64115>\
**Category:** PragProg Customers\
**Tags:** question, book-hands-on-rust\
**Created:** [14 July 2022 10:57 UTC](https://forum.devtalk.com/t/hands-on-rust-how-do-i-debug-a-call-chain-in-rust/64115 "2022-07-14T10:57:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Keton](https://forum.devtalk.com/letter_avatar_proxy/v4/letter/k/e95f7d/32.png) [@Keton](https://forum.devtalk.com/u/Keton)\
**Post date:** [14 July 2022 10:57 UTC](https://forum.devtalk.com/t/hands-on-rust-how-do-i-debug-a-call-chain-in-rust/64115/1 "2022-07-14T10:57:35Z")

</div>

When running the program in chapter 8, “Implementing Combat”, the printout _Health before attack_ was never printed so I assumed something was wrong in the call chain.

How would I go about debugging this call chain (`ecs.entry_mut(*victim).unwrap()...`)?

```auto
#[system]
#[read_component(WantsToAttack)]
#[read_component(Health)]
pub fn combat(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
    ...
    victims.iter().for_each(|(message, victim)| {
        if let Ok(mut health) = ecs
            .entry_mut(*victim)
            .unwrap()
            .get_component_mut::<Health>()
        {
            println!("Health before attack: {}", health.current);
            ...
        }
        commands.remove(*message);
    });
}

```

After some comparing of source code, I found out that I had actually written `read_component(Health)` instead of `write_component(Health)`.

```auto
#[system]
#[read_component(WantsToAttack)]
#[write_component(Health)]
pub fn combat(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
    ...
}

```

This is my first encounter with Rust but I was surprised that this error slipped by the compiler. I expected similar error as if I hade left out some **mut** …

---

<div class="post-metadata">

**Author:** ![Red](https://forum.devtalk.com/user_avatar/forum.devtalk.com/red/32/4306_2.png) [@Red](https://forum.devtalk.com/u/Red)\
**Post date:** [14 July 2022 12:11 UTC](https://forum.devtalk.com/t/hands-on-rust-how-do-i-debug-a-call-chain-in-rust/64115/2 "2022-07-14T12:11:51Z")

</div>

I don’t own this book so I cannot comment on the code, but here are a few tricks I use to debug chained methods and see the intermediate values. I’m using the IntelliJ plugin.

To just see the _types_ at different point, the same techniques can be used - check values in a map, or split the chained method into several intermediate variables.

To take a dummy example:

```rust
    let values = vec!["one", "two", "three"];
    let values_str = values.iter()
        .enumerate()
        .map(|(i,s)| {
            format!("{}: {}", i + 1, s) // <== breakpoint here
        })
        .collect::<Vec<_>>()
        .join(", "); // <== breakpoint here
    println!("Result: {}", values_str);

```

It’s possible to place a breakpoint on the map closure. Make sure to use a block with ‘{ … }’ and that the code is not on the same line. Otherwise, values are not visible:

```rust
        .map(|(i,s)| { format!("{}: {}", i + 1, s) }) // <== I cannot see anything

```

It’s also possible to put breakpoints on the lines after, but on the lines before it’s a bit tricky because it’s an iteration and there is no closure to expose any value. The debugger will stop but will not show anything. Sometimes you may be able to step into the function and catch something from there, but it’s tedious.

One way to look is to insert a dummy identity map. For example if I want to catch the values before the enumerate:

```rust
    let values_str = values.iter()
        .map(|x| {
            x // <== breakpoint here
        })
        .enumerate()
        .map(|(i,s)| { format!("{}: {}", i + 1, s) })
        .collect::<Vec<_>>()
        .join(", ");

```

You can even put a `println!()`, that’s usually easier than looking at the values in the debugger.

Another way is to simply split the calls and store the intermediate result in temporary variables. Note the `clone()` to avoid losing ownership on the intermediate data:

```rust
    let values = vec!["one", "two", "three"];
    let values_str_1 = values.iter()
        .enumerate();
    let debug = values_str_1.clone().collect::<Vec<_>>();
    let values_str = values_str_1 // <== breakpoint
        .map(|(i,s)| { format!("{}: {}", i + 1, s) })
        .collect::<Vec<_>>()
        .join(", ");
    println!("Result: {}", values_str);

```

PS: I found out that with that plugin, you had disable the NatVis renderers if you examine the values in the LLDB view, otherwise you get a lot of warnings hindering the view:

 ![image](https://forum.devtalk.com/uploads/default/original/2X/9/97f3d30aa6e5165a3dcc2b53a9f795683d1d7bc1.png)

---

<div class="post-metadata">

**Author:** ![herbert](https://forum.devtalk.com/user_avatar/forum.devtalk.com/herbert/32/1233_2.png) [@herbert](https://forum.devtalk.com/u/herbert)\
**Post date:** [14 July 2022 12:23 UTC](https://forum.devtalk.com/t/hands-on-rust-how-do-i-debug-a-call-chain-in-rust/64115/3 "2022-07-14T12:23:33Z")

</div>

Hi,

Thanks for reading the book!

Unfortunately, Legion (the ECS) is responsible for the `World` access (which is what the `read_component` is handling) - and doesn’t flag that one at compile time. I really wish it did!

The issue can be caught by changing the `if let`. `if let` is like a single-case `match`, so it’s only running the enclosed code if `get_component_mut` succeeds - and continues on its way if it fails.

`get_component_mut` returns a `Result` type. So you have a few options for handling this:

The simplest way, not very specific:

```rust
if let Ok(mut health) = ecs.entry_mut(*victim).unwrap().get_component_mut::<Health>() {
} else {
     // Print an error here
}

```

Using `match`:

```rust
match ecs.entry_mut(*victim).unwrap().get_component_mut::<Health>() {
    Ok(mut health) => { // do the health deduction }
    Err(msg) => { // Handle the error, msg will tell you what went wrong }
}

```

Or you can choose to crash when things go wrong (surprisingly helpful for debugging):

```rust
let mut victim = ecs.entry_mut(*victim).unwrap().get_component_mut::<Health>().unwrap();
// Health deduction code

```

Hope that helps!
