There was a post and discussion on reddit yesterday that reminded me I wanted to write about stack traces in rust at some point.

I’ve worked on a bunch of java code bases over the years, and one feature I like about the java environment is that you can obtain a stack trace identifying the throw site of any exception raised and a some good information about the path the code took to get there.

This is really valuable in a production system where a subtle environment change triggers an unexpected violation of an invariant. The violation is unexpected and so the error bubbles all the way up to the generic error handling. Luckily because of the stacktrace you still have context from which to quickly diagnose the error and decide on an appropriate course of action.

Rust currently supports printing a stack trace to stderr when a thread panic!()s, which is really handy. It is enabled by setting the “RUST_BACKTRACE” environment variable. Panics however are too heavyweight to use for most errors in rust code because they offer limited recovery options, and instead it is generally preferred to return std::result::Result.

(Aside: I suspect in the long run panics will all-but disappear from rust. My guess is that some nice sugar will come along for Result types that will make e.g. array indexing with Results palatable (maybe something like ‘?’ syntax), and then panics will become relegated to a small corner of the language, used only for out-of-memory errors and maybe stack overflows.)

So that leaves a problem: How do I get a stacktrace out of an unexpected rust error in production code? The best approach I’ve come up with so far is to combine a custom error with rt::backtrace. Here’s the recipe: