Your application may panic for a number of reasons (e.g. when you call .unwrap() on a None). And
when this happens, you want to be a good citizen and:
provide a useful stacktrace so that they can report errors back to you.
not leave the users terminal state in a botched condition, resetting it back to the way it was.
better-panic
better-panic gives you pretty backtraces for panics.
Here’s an example of initialize_panic_handler() using better-panic to provide a prettier
backtrace by default.
I personally like to reuse the Tui struct in the panic handler.
That way, if I ever decide to move from crossterm to termion in the future, there’s one less
place in the project that I have to worry about refactoring.
Here’s an example of initialize_panic_handler() using
better_panic and
libc to provide a prettier backtrace by default.
Now, let’s say I added a panic! to an application as an example:
This is what a prettier stacktrace would look like with better-panic:
With .most_recent_first(false) the last line of the stacktrace is typically where the error has
occurred. This makes it fast and easy to find the error without having to scroll up the terminal
history, and iterate on your application rapidly during development.
This kind of detailed stacktrace is only available in debug builds. For release builds, you may get
inlined or truncated stacktraces.
For example, here’s what I get when I compile with all optimizations on:
This is not particularly useful to show to the average user. We’ll discuss better solutions for what
to show the users of your application in the following subsections.
human-panic
To use human-panic, you’ll have to install it as a
dependency:
Personally, I think human-panic provides the most user friendly panic handling functionality out
of the box when users experience an unexpected panic:
It generates a report where information relevant to the crash is logged. Here’s the content of the
temporary report file that human-panic creates (with optimizations turned on):
In debug mode, the stacktrace is as descriptive as earlier.
Configuration
You can mix and match these different panic handlers, using better-panic for debug builds and
color-eyre and human-panic for release builds. The code below also prints the color-eyre
stacktrace to log::error! for good measure (after striping ansi escape sequences).
Here’s code you can copy paste into your project (if you use the
Tui struct to handle terminal exits):