Is there a nice way to track line number?
Closed this issue · 4 comments
ibaryshnikov commented
Something like
.context(concat!(file!(), ":", line!()))
but a bit more concise
dtolnay commented
You could make a macro that captures both in one call:
use anyhow::{bail, Context, Result};
macro_rules! here {
() => {
concat!("at ", file!(), " line ", line!(), " column ", column!())
};
}
fn f() -> Result<()> {
bail!("oh no!");
}
fn main() -> Result<()> {
f().context(here!())?;
Ok(())
}
Error: at src/main.rs line 14 column 17
Caused by:
oh no!
Or get a little fancier with an extension trait:
use anyhow::{bail, Context, Result};
use std::fmt::Display;
pub struct Location {
file: &'static str,
line: u32,
column: u32,
}
pub trait ErrorLocation<T, E> {
fn location(self, loc: &'static Location) -> Result<T>;
}
impl<T, E> ErrorLocation<T, E> for Result<T, E>
where
E: Display,
Result<T, E>: Context<T, E>,
{
fn location(self, loc: &'static Location) -> Result<T> {
let msg = self.as_ref().err().map(ToString::to_string);
self.with_context(|| format!(
"{} at {} line {} column {}",
msg.unwrap(), loc.file, loc.line, loc.column,
))
}
}
macro_rules! here {
() => {
&Location {
file: file!(),
line: line!(),
column: column!(),
}
};
}
fn f() -> Result<()> {
bail!("oh no!");
}
fn main() -> Result<()> {
f().location(here!())?;
Ok(())
}
ibaryshnikov commented
No way to go without a macro, I guess? Well, even like this, it's almost perfect :) Do you plan adding such macro to a crate itself?
est31 commented
std errors will contain backtraces in the future: rust-lang/rust#53487
ibaryshnikov commented