Always had the problem that if I wanted to just log an error, rather than bubble it all the way up to main(), that you wouldn’t get a stacktrace. You could iterate the source chain and plug the stacktrace together yourself, but it’s rather complex code.

Now I realized, you can do this to get a stacktrace:

let error = todo!("Get an error somehow...");
let error = anyhow::anyhow!(error); //converts to an `anyhow::Error`
eprintln!("Error with stacktrace: {error:?}");

For converting to an anyhow::Error, it often also makes sense to use anyhow::Context like so:

use anyhow::Context;
let error = error.context("Deleting file failed.");
  • TehPers@beehaw.org
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    13 hours ago

    Adding context does two things:

    • Add additional messages to the error for debugging purposes
    • Attach data to the error for the callers

    For the former, I prefer all lowercase, very concise, and with the intent to describe what beebboop was doing when it failed (in your example). More practically, what produced the error could be writing to the filesystem, and the additional context could be that the filesystem was being written to because it was saving a config file.

    For the latter, this is actually a lot different. anyhow lets you downcast its errors into any of its contexts. You can use this to create aggregated errors, test for specific contexts, or attach useful details to the error which might help with recovering from it.