aboilque
aboilque

Reputation: 63

How can I get file and line number where an error was returned?

Suppose I call function f().unwrap() which calls calls function g. The g function returns an Error wrapped in Result, and f propagates this error. Then I get the message that thread panicked at line where I called f().unwrap().

I would like to know is the place where error was returned, i.e. where g returned error. This would be much more informative, is there any way to achieve this?

Upvotes: 3

Views: 3278

Answers (2)

Chayim Friedman
Chayim Friedman

Reputation: 70970

If you return anyhow::Error, and you turn on the backtrace feature of anyhow, you can retrieve a backtrace from the error if you will set the environment variable RUST_BACKTRACE or RUST_LIB_BACKTRACE to 1:

let error: anyhow::Error;
eprintln!("{}", error.backtrace());

Upvotes: 5

cafce25
cafce25

Reputation: 27337

You can do it but you have to collect and attach the info yourself:

With anyhow you can add context to an error with the context method.

fn main() {
    f().unwrap();
}

fn f() -> Result<(), anyhow::Error> {
    g().map_err(|e| e.context(format!("at {}:{}:{}", file!(), line!(), column!())))?;
    Err(anyhow::anyhow!("some other error"))
}

fn g() -> Result<(), anyhow::Error> {
    Err(anyhow::anyhow!("oh noes"))
}

Or you can wrap the error in your own error type containing the info.

fn main() {
    f().unwrap();
}

#[derive(Debug)]
struct Error {
    file: &'static str,
    line: u32,
    column: u32,
    error: GError,
}

#[derive(Debug)]
struct GError;

fn f() -> Result<(), Error> {
    g().map_err(|e| Error {
        file: file!(),
        line: line!(),
        column: column!(),
        error: e,
    })
}

fn g() -> Result<(), GError> {
    Err(GError)
}

Upvotes: 2

Related Questions