Where is the anyhow! macro?

I have been using the anyhow to provide some context to my error Results, which works fine.

But now I find I can't create my own errors, even the simple examples from the anyhow docs do not work for me:

use anyhow::Result;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum FormatError {
    #[error("Invalid header (expected {expected:?}, got {found:?})")]
    InvalidHeader {
        expected: String,
        found: String,
    },
    #[error("Missing attribute: {0}")]
    MissingAttribute(String),
}

fn main() -> Result<()> {
    let missing = 0;
    let attr = String::new();

    return Err(FormatError::MissingAttribute(attr));

    return Err(anyhow!("Missing attribute: {}", missing));
}

Errors out with:

$ cargo run
   Compiling junk v0.1.0 (/mnt/c/Users/zicog/conveqs/junk)
error: cannot find macro `anyhow` in this scope
  --> src/main.rs:21:16
   |
21 |     return Err(anyhow!("Missing attribute: {}", missing));
   |                ^^^^^^

error[E0308]: mismatched types
  --> src/main.rs:19:16
   |
19 |     return Err(FormatError::MissingAttribute(attr));
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `anyhow::Error`, found enum `FormatError`

Where is that pesky anyhow! macro hiding?

What do I have to do to get the "FormatError" example working?

I have this in Cargo.toml

[dependencies]
anyhow = "1.0"
thiserror = "1.0"

Ah ha! This compiles:

use anyhow::Result;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum FormatError {
    #[error("Invalid header (expected {expected:?}, got {found:?})")]
    InvalidHeader {
        expected: String,
        found: String,
    },
    #[error("Missing attribute: {0}")]
    MissingAttribute(String),
}

fn main() -> Result<()> {
    let missing = 0;
    let attr = String::new();

    return Err(anyhow::Error::new(FormatError::MissingAttribute(attr)));

    return Err(anyhow::anyhow!("Missing attribute: {}", missing));
}

Why don't the anyhow docs do that? What am I doing wrong?

The macro is available as anyhow::anyhow!. You can use that to write the short form: use anyhow::anyhow.

To turn your FormatError into the error your function is expected to return you need to turn it into that:

return Err(FormatError::MissingAttribute(attr).into());

The question mark operator would do that automatically for you:

Err(FormatError::MissingAttribute(attr))?;
1 Like

Thanks jer.

I found the anyhow! eventually.

I wish they had mentioned these little details on their front page: https://docs.rs/anyhow/1.0.32/anyhow/ that have save a wasted morning!

A little tip is searching for anyhow in the doc:

1 Like

Thanks. I spend a lot of time running around docs. They are very good and complete as far as I can tell but I have a struggle finding what I need and/or making any sense out of it.

What is that tool you are searching docs with?

docs.rs as always. Or rarely I clone the repo and grep for it.

That does not look anything like my doc.rs. Which look like this:
https://docs.rs/

and ends up looking like this:
https://docs.rs/anyhow/1.0.32/anyhow/

If I happen to know already that the anyhow crate might be useful.

Which is where my problems began...

I mean, if you know the right crate name, the documentation of it has to be https://docs.rs/<crate_name>, unless they don't want to public the crates to https://crates.io . In crate documentation, you could search for any public items of the crate, including macros.

Business as usual then. Most of the time my problem is I have no idea what it is I'm looking for.

For example that .into() thing, would never have guessed I needed one.

1 Like

Thanks again.

I have now removed hundreds of unwraps() from my multi-threaded monster and get nice error messages when thing go sideways.

1 Like