That's because the types of errors where you want a stack trace are a relatively small subset of all possible errors.
Stack traces are only useful for errors that indicate a bug in the program, i.e. something a programmers has to respond to. It's not useful for the vast class of bugs that are a result of wrong input, wrong external state, or infrastructure issues.
Rust projects tend to favor panicking over error handling for programmer bugs (which does indeed give you a stack trace depending on environment variables), or even better encoding the invariants in the type system, but there are cases where an error coming from a library are truly, actually unexpected, so both `anyhow` and `thiserror` do provide support for attaching a stack trace in those situations.
This sounds disingenuous. They explained why the language doesn't force stack traces on all errors, and then explained how to get them if you want them.
I see a very opinionated explanation, not a "this is why the language does not" explanation.
>Stack traces are only useful for errors that indicate a bug in the program, i.e. something a programmers has to respond to. It's not useful for the vast class of bugs that are a result of wrong input, wrong external state, or infrastructure issues.
This is a personal opinion, not something you can declare as the objective truth. There is a lot of value in seeing what path the program took before it encountered a eg. validation error.
>but there are cases where an error coming from a library are truly, actually unexpected, so both `anyhow` and `thiserror` do provide support for attaching a stack trace in those situations.
This is wrong because it's up to the library to attach the stacktrace, not the userland code using the library, so saying "you can get them if you want them" is not true.
If the author of the library did not decide to attach the stacktrace, your only option is wrapping it yourself, which you can only do if you already know up front all the paths that can fail. Also, you are not supposed to expose errors from a library with anyhow, they are only for application/top level code.
I'm curious, what's the value of a stack trace of another person's library functions? As mentioned, you can get a stack trace that includes all of your code, that's what was offered to you.
The only thing a library gathering a stack trace instead of you gives you is that it includes traces through code you didn't write & ostensibly aren't responsible for. If you're going to go to the effort of tracing through a dependencies code, you might as well add the stack trace yourself; it's a single line of code from the standard library to collect it, std::backtrace::Backtrace::capture().
EDIT: capture will only actually grab a trace when env vars say it should, you can use force_capture to ignore those. To get to why this isn't the default for errors you're asking for, here's a line from their documentation:
> Capturing a backtrace can be both memory intensive and slow
Ideally (in my ideal world), it would be Result<T, E> that holds the backtrace. The value is that I don't know up front which method call is going to cause an error that is hard to track down, which is why I don't see how "instrument your calls with backtrace yourself" helps. It requires that I already have some idea about the execution path, otherwise I don't know where to put the backtrace instrumentation.
Since Backtrace::capture() is already tied to an env var, we could have the backtrace on Result without affecting performance, since you would only enable it for debugging. This would allow you to eg. easily track down a situation where you see in your prod logs that you are encountering a lot of "validation error: string is too long" but you can't tell where it is coming from. Flip the env var, redeploy the application, read the backtrace, turn off the env var, fix the problem.
Stack traces are only useful for errors that indicate a bug in the program, i.e. something a programmers has to respond to. It's not useful for the vast class of bugs that are a result of wrong input, wrong external state, or infrastructure issues.
Rust projects tend to favor panicking over error handling for programmer bugs (which does indeed give you a stack trace depending on environment variables), or even better encoding the invariants in the type system, but there are cases where an error coming from a library are truly, actually unexpected, so both `anyhow` and `thiserror` do provide support for attaching a stack trace in those situations.