by JoelJacobson on 8/23/23, 5:37 AM with 91 comments
by afdbcreid on 8/23/23, 12:59 PM
use std::error::Error as StdError;
use std::panic::Location;
use std::fmt;
#[derive(Debug)]
pub struct MyError {
pub error: Box<dyn StdError + Send + Sync>,
pub location: &'static Location<'static>,
}
impl<E: StdError + Send + Sync + 'static> From<E> for MyError {
#[track_caller]
#[inline]
fn from(error: E) -> Self {
Self {
error: Box::new(error),
location: Location::caller(),
}
}
}
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}, {}", self.error, self.location)
}
}
We can also optimize this more (e.g. a simple optimization to be two words instead of three: https://play.rust-lang.org/?version=stable&mode=debug&editio.... Also allows opting `Send` and `Sync` out or using non-`'static` lifetimes), but this works as a baseline. The only disadvantage is that if called in a function with `#[track_caller]` this will report the location of the caller... But this is something I can live with.by diarrhea on 8/23/23, 7:24 AM
Side note: can we make 'file not found' errors that fail to mention what wasn't found illegal? What's the point of 'file not found', then keeping silent about the exact file? Seen it in various ecosystems now.
[0]: https://www.lurklurk.org/effective-rust/macros.html#when-to-...
by dathinab on 8/23/23, 7:31 AM
Through also note that async code has ... not so nice backtraces, for now, even if you only care about the calling location.
by tasn on 8/23/23, 10:27 AM
I wodner if anyone is doing anything better? The nice thing about our approach is that we store the data on each error, so we get a full backtrace, even when using async.
1: https://github.com/svix/svix-webhooks/blob/main/server/svix-...
2: https://github.com/svix/svix-webhooks/blob/main/server/svix-...
by JoelJacobson on 9/2/23, 9:13 AM
by imetatroll on 8/23/23, 7:19 AM
by dannymi on 8/23/23, 7:26 AM
What will the end user do with rs source code file&line?
I read the example on the page. What they want to do is return which argument of `add` the error was with. Well, then introduce an `AddError` (or I guess it could be a more generic `BinaryOperationError`) like this: `struct AddError { argument_1: Option<...>, argument_2: Option<...> }` and return that error from `add`. Then you can even have it return errors due to both arguments at the same time.
One use case of the crate would be if you made a mistake and something actually shouldn't be an error but should be a panic, and you wanna find where it is in order to change it to a panic. So, debugging.
by lewantmontreal on 8/23/23, 8:53 AM
I’ll have to check if this macro is an easier solution!
by olih_ on 8/23/23, 9:09 AM
by Animats on 8/23/23, 7:08 AM
by sidit77 on 8/23/23, 10:28 AM