3 ms·
You seem to be arguing more for stack traces than for exceptions? Rust can store backtraces in value objects as well [0]. It's opt-in (capturing a stack trace
by whytevuhuni 2y ago
You seem to be arguing more for stack traces than for exceptions?
Rust can store backtraces in value objects as well [0]. It's opt-in (capturing a stack trace at the error value's creation may be expensive if that error is eventually handled), but with the anyhow crate you get a decent compromise: a stack trace is captured at the boundary of your program and libraries during the conversion, and then shown only if the error bubbles up to main().
And you get the bonus of storing both the stack trace, and relevant context where needed, e.g. to show values of parameters. Here's how that playground example above fails:
Error: Second try
Caused by:
0: Parsing 'forty-two' as number
1: invalid digit found in string
Stack backtrace:
0: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from
at ./.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.94/src/backtrace.rs:27:14
1: <core::result::Result<T,F> as core::ops::try_trait::FromResidual<core::result::Result<core::convert::Infallible,E>>>::from_residual
at ./.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:2009:27
2: playground::parse_number
at ./src/main.rs:25:8
3: playground::parse_and_increment
at ./src/main.rs:18:18
4: playground::main
at ./src/main.rs:7:19
...
[0] https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=99dbbbc70875df5fdd44d90e2dbf7c69 https://play.rust-lang.org/?version=stable&mode=debug&editio...
- tsimionescu 2y agoCool, I didn't know about RUST_BACKTRACE = 1. That addresses the core of my comment, yes. I will note that some runtimes (like Java or C#, I believe) don't compute the stack trace unless and until it is requested, which means that exceptions that are caught and handled without being logged shouldn't incur the performance cost - thus removing most of the reason you may want to have a way to disable this behavior. I did know about anyhow, that was exactly the library I was mentioning. But that requires manually adding context at all places where the error is passed.
- neonsunset 2y agoExceptions thrown in both Java and .NET eagerly compute the stack trace and the text associated with it. They are also very expensive compared to the happy path. Historically, manually thrown exceptions in OpenJDK have been cheaper than .NET's (although .NET 9 makes them twice as cheap) while NPE's in OpenJDK are much more expensive than regular Java exceptions or .NET's NREs In Java, you can disable stack traces altogether that massively reduces the cost (which is what e.g. Crafting Interpreters suggests - it's a good course but the author is both wrong and actively misleading about cost model of implementations covered in parts 1 and 2 because of this) but few codebases do this.