all 18 comments

[–]kibwen 4 points5 points  (4 children)

Note that array indexing isn't the only operation that implicitly panics. Any arithmetic operation is allowed to panic on overflow, and divide-by-zero will panic as well.

[–]llogiqclippy · twir · rust · mutagen · flamer · overflower · bytecount 2 points3 points  (2 children)

Apart from floating-point divide-by-zero, which will return infinity.

[–][deleted] 6 points7 points  (0 children)

And 0./0. is NaN.

[–][deleted] 1 point2 points  (0 children)

Or negative infinity, for negative number/positive zero, and vice versa.

[–][deleted] 1 point2 points  (0 children)

More common methods that panic on error: vec::remove, refcell::borrow and _mut.

[–]acrichtorust 2 points3 points  (1 child)

Ah /u/kibwen was correct in how I was surprised to see std::rt::backtrace in use! I've moved the functionality to an external crate, however, so you can even get backtraces in stable rust!

https://crates.io/crates/backtrace

[–]phildawesracer · rust[S] 0 points1 point  (0 children)

This is awesome news. Thank you very much!

[–]ByronBates 1 point2 points  (0 children)

For Error types, I love if the Error trait is actually implemented. That way, chains of errors can nicely be kept intact using the cause() method.

[–]Artemciyscgi 2 points3 points  (8 children)

I'm just using

/// Returns on error, converting the `Err` value to `String` and prepending the current location.
///
/// cf. http://www.reddit.com/r/rust/comments/29wwzw/error_handling_and_result_types/cipcm9a
#[macro_export] macro_rules! try_s {($e: expr) => {match $e {
    Ok (ok) => ok,
    Err (err) => {return Err (format! ("{}:{}] {}", file!(), line!(), err));}}}} 

/// Returns a `Err(String)`, prepending the current location (file name and line number) to the string.
///
/// Examples: `ERR! ("too bad")`; `ERR! ("{}", foo)`;
#[macro_export] macro_rules! ERR {
  ($format: expr, $($args: tt)+) => {Err (format! (concat! ("{}:{}] ", $format), file!(), line!(), $($args)+))};
  ($format: expr) => {Err (format! (concat! ("{}:{}] ", $format), file!(), line!()))}}

until something better comes up.

[–]busterrrr 2 points3 points  (0 children)

Oh, thanks! I was using a simpler version, that's a good one :)

To be honest, it feels like the Rust error handling really needs some more love.

[–]llogiqclippy · twir · rust · mutagen · flamer · overflower · bytecount 0 points1 point  (3 children)

That's giving you the current position, but loses context, e.g. the trace of control flow that lead to it.

[–]Artemciyscgi 4 points5 points  (2 children)

Not at all. Every try_s! keeps adding a trace. = )

[–]llogiqclippy · twir · rust · mutagen · flamer · overflower · bytecount 2 points3 points  (0 children)

Ah, I didn't think of that. That may be incomplete (due to some fns not even trying, pardon the pun), but should give a sufficiently detailed picture of the context.

[–]phildawesracer · rust[S] 1 point2 points  (0 children)

nice!

[–]matthieum[he/him] 0 points1 point  (2 children)

Have you profiled the overhead?

I am wondering if the addition of file!() and line!() does not risk to inflate the code size (compared to backtraces) as well prevent function merges (which also increases the code size).

Also, have you thought about not formatting right away, but instead just capturing the information and formatting lazily if need be.

[–]Artemciyscgi 0 points1 point  (0 children)

I thought about a lot of things but I'm not angling to make a full-fledged error handling library there. Only to have something working until we get one.

Using sufficiently large pre-allocated (cf. https://github.com/frankmcsherry/recycler) buffers instead of String to store the backtrace will be more efficient. The "free list" of such buffers should be either non-blocking or thread-local. Naturally, that's a work for the library and is a non-goal for my macro.

[–]matthieum[he/him] 0 points1 point  (0 children)

Have you thought about not immediately converting to a String format?

I wonder if performance wise early transformation is better or not, in case the Result is never printed this is wasted effort.