Git Product home page Git Product logo

color-backtrace's Introduction

color-backtrace

Crates.io docs.rs MIT licensed Apache 2.0 licensed

A Rust library that makes panics a little less painful by nicely colorizing them and printing the relevant source snippets.

[dependencies]
color-backtrace = { version = "0.6" }

To enable it, simply place this code somewhere in your app initialization code:

color_backtrace::install();

If you want to customize some settings, you can instead do:

use color_backtrace::{default_output_stream, BacktracePrinter};
BacktracePrinter::new().message("Custom message!").install(default_output_stream());

Features

  • Colorize backtraces to be easier on the eyes
  • Show source snippets if source files are found on disk
  • Print frames of application code vs dependencies in different color
  • Hide all the frames after the panic was already initiated
  • Hide language runtime initialization frames

Usage in tests

Unfortunately, defining custom init functions run before tests are started is currently not supported in Rust. Since initializing color-backtrace in each and every test is tedious even when wrapping it into a function, I recommended using the ctor crate for this.

Somewhere, preferably in your crate's main module, put the following code:

#[cfg(test)]
mod tests {
    use ctor::ctor;

    #[ctor]
    fn init_color_backtrace() {
        color_backtrace::install();
    }
}

You can also do this outside of a #[cfg(test)] section, in which case the panic handler is installed for both test and regular runs.

Screenshot

Screenshot

color-backtrace's People

Contributors

ajyoon avatar athre0z avatar haze avatar repi avatar robatipoor avatar s1341 avatar windsoilder avatar yaahc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

color-backtrace's Issues

Colorful backtrace for Failure & co

So I'm trying to color the backtrace while having my own Error type. Here is the thing, I want to use the rust way of returning errors. All errors propagate to the main() function and are returned there.

fn main() -> Result<()> {
... code goes here
}

Is there a way to catch the error/backtrace from the main() function? How do you integrate with color-backtrace?

`color_backtrace::install()` panics if `TERM` environment variable is not set

More specifically, color_backtrace::Settings::default() may panic on let term = term::stderr().unwrap();. term uses a number of heuristics to determine how to populate it's TermInfo struct, and the first and simplest is reading the TERM env var, and branching based on that. When TERM is unset, term::stderr() will return None.

I hit this condition in a Buildkite CI system, which (I believe) uses execve to control the execution context -- most notably the build agent's environment. As it doesn't set TERM, my automatic tests started exploding as soon as I updated from color_backtrace 1.3 to 2.0.

My work-around is currently to check if std::env::var("TERM").is_ok() before calling color_backtrace::install() but that seems to be a rather brittle and lack-luster solution. My first instinct would be to change the signature of install() to something like pub fn install() -> Result<(), ???> but I'm 1) not familiar with how you're managing Error types in this library, and 2) not terribly comfortable with the idea of editing some of this library's most visible API without having a chat about it first.

Let me know if you have any questions about my issue, or if I might be able to help resolve it in the library.

Usage with tests

Is it possible to somehow use this for panics in tests? It may help me with debugging.

Document SNAFU backtrace printing integration

I'm currently in the process of porting a project from failure to SNAFU to try it out and I'd like to be able to use color-backtrace with SNAFU backtraces. They also use an opaque wrapper type same as failure, though theirs is a much simpler wrapper, just a NewType, so doing the hacky failure style integration should be trivial.

I would however like to communicate with the SNAFU devs and the failure devs and the guy who works on std that I talked to last time who had plans for getting backtraces into the std::error::Error API and make sure everyone is on the same page so all the integration eventually gets done the right way.

Since it seems that SNAFU already has a way to extract the inner backtrace::Backtrace, I propose that color-backtrace's README should be updated to document this fact, along side the existing notes on how to integrate with failure.

I'm planning on getting to this soonish

Remove support for failure backtrace printing

Right now failure is in the process of being deprecated, as such color-backtrace shouldn't have special case support for failure since it may encourage users to use a deprecated error handling crate that is no longer compatible with the rest of the ecosystem.

Consider changing indentation level to better match ecosystem defaults

Disclaimer: I know this is a really frivolous change, I absolutely don't mind if you don't do this, but I think it might be a nice to have.

Right now std::backtrace::Backtrace and tracing_error::SpanTrace default to printing with 4 spaces of leading indentation. anyhow and eyre both default to this same level of indentation when printing errors in a chain of errors. And tho eyre makes it relatively easy to update the indentation by overriding the report format, I think it might be a good idea to use 4 instead of 2 spaces.

Heres what it looks like naively if you print backtraces and spantraces both with and without the color printers

Screenshot from 2020-04-29 10-45-47

"Oh noez! Panic! ๐Ÿ’ฅ" may be seen as unprofessional

Hi, thanks for the great library. One of a few things I noticed that could be improved is the message that greets you in the backtrace - "Oh noez! Panic! ๐Ÿ’ฅ". It makes it seem as if a panic is a minor issue - and it may be so during development. But when it happens in production and the client sees that in an error message, he may think his problems are not being taken seriously by the developers.

Do you think it would be possible to change it or get rid of it?

Relicense as MIT/Apache2?

Hi there!

I wanted to ask if it would be possible to relicense this crate as MIT/Apache2. In theory, MIT is more restrictive than Apache 2, but apparently there are some possible problems with MIT, especially when it comes to trademarks (or so I heard). Most crates in the Rust eco system are dual licensed as MIT/Apache2, so it would be great if this one would be as well ^_^

Support usage with `std::fmt` when printing backtraces

Right now the print_backtrace function just immediately dumps output to stderr, when attempting to use this inside of a Display method of another type however will cause the output to be displayed out of order, because it is not being formatted to the same buffer as the rest of the output.

Screenshot from 2020-04-24 07-58-32
Screenshot from 2020-04-24 07-57-29
Screenshot from 2020-04-24 07-57-17

We should change print_backtrace to better interact with the Display and Debug traits in std, either by returning a type that implements the print logic or by taking a formatter as an argument when printing.

The `backtrace` dependency always builds with `features = ["gimli-symbolize"]`

At the time of writing, Cargo intentionally unifies features before it prunes dependencies behind [build-dependencies], [target.'cfg(...)'.dependencies], and similar sections. See rust-lang/cargo#1197 and rust-lang/cargo#2524 for some discussion about that behavior. I also have a minimal demonstration of surprising unifications in a playground repo of mine.

This is a direct problem for me because I'm trying to write library code that can compile for both native targets (macos, windows, etc.) and WASM. The plan is to include color_backtrace only on non-WASM targets. It is, currently, impossible to compile backtrace with features = ["gimli-symbolize"] activated for WASM targets. (Why that is takes a bit of explaining; feel free to ask if you're curious.) That means if color_backtrace is anywhere in my dependency graph -- even pruned behind a [target.'cfg(not(target_arch = "wasm32"))'.dependencies] section -- "gimli-symbolize" will be activated for the build's backtrace dependency, and the compilation will fail.

One solution for my build failure, and something to consider for this crate generally, would be moving the "gimli-symbolize" activation from a target-specific dependency to a re-exported feature. Something like this,

[features]
default = []
optimize_for_unix = ["backtrace/gimli-symbolize"]

[dependencies]
backtrace = "0.3"

If I can't work-around this class of error in some other way, I'll likely open a PR with that change in the next few days.

RUST_BACKTRACE=full can't find source files if the running application changes its working directory

This version will print source lines

    panic!();
    std::env::set_current_dir(git_dir)?;

this version will hit the subsequent line in color-backtrace/src/lib.rs and skip printing all the src lines.

    std::env::set_current_dir(git_dir)?;
    panic!();
214             Err(ref e) if e.kind() == ErrorKind::NotFound => return Ok(()),

The filenames in my binary all use relative paths, I noticed that in your screenshot it seems to use absolute paths.

I imagine the fix is as simple as generating the rust binaries with absolute paths in the debug info, but I have no idea how to force it to compile that way. Either that or store the crate root somewhere in the binary and use that during filename resolution rather than expecting it to work relative to the current directory.

Support custom filtering for pre_panic frames

I already added this to my patched version when I was prototyping color-eyre, so I'll open the PR for this, but the idea is to support the following

            let settings = color_backtrace::Settings::default().add_post_panic_frames(&[
                "<color_eyre::Context as eyre::EyreContext>::default",
                "eyre::",
            ]);

on-demand usage via cargo command/wrapper

Being able to use this crate to aid in debugging without adding it to every project or when needed seems like it would be a nice frictionless way to get better backtraces, and helps with things like #3.

I've started sketching out a cargo subcommand for this, and am considering an alias or wrapper that would make RUST_BACKTRACE=color a more transparent/automatic thing. Though it seems to work well enough, the interaction with cargo and the linker is somewhat fragile with this approach. Is there any interest in offering or maintaining something similar or would it be best to keep this separate?

Provide custom frame filtering option

I'm using color-backtrace along with rayon.

The trouble is that rayon produces absurdly long stack traces. I'm looking at one with 150 frames right now.

These long stack traces push my interesting stack traces way way up my scroll buffer.

I'd like to filter out the rayon stack frames. Its probably too much to task for color-backtrace to do it for me, but it'd be nice if I had the option to provide custom filtering logic.

Coloring is broken in IntelliJ since "Only colorize output when printing to a tty"

Since version 0.2.0 coloring of backtraces doesn't work in IntelliJ with Rust plugin. The backtraces are printed as normal text, for me as white on gray background.

I narrowed down the bug to commit ec5803a - "Only colorize output when printing to a tty". I don't know what IntelliJ does under the hood, but it seems it redirects output to a file? Maybe the plugin's source code holds the answer - https://github.com/intellij-rust/intellij-rust

Steps to reproduce:

  1. Assuming you have IntelliJ with Rust plugin, create new project with File -> New -> Project.
  2. Choose Rust template, click Next, name the project, click Finish.
  3. Use these files:
    src/main.rs:
fn main() {
    color_backtrace::install();
    panic!("I'm panicking");
}

Cargo.toml

[package]
name = "color-backtrace-test"
version = "0.1.0"
authors = ["John Smith"]
edition = "2018"

[dependencies]
#color-backtrace = "0.1.3" # works
#color-backtrace = "0.2.0" # doesn't work
#color-backtrace = {git = "https://github.com/athre0z/color-backtrace", rev = "0c72936b02ad9f78fe7df87d9364bb3eeffcce67"} # works
color-backtrace = {git = "https://github.com/athre0z/color-backtrace", rev = "ec5803ad5ff9e60888f0dfdf6492b4c2fcadd373"} # doesn't work
  1. On the right click "Add configuration".
  2. In the dialog on the left click "+" -> Cargo Command
  3. The "Command" field should say "run", you can fill the "Name" field as "cargo run", click Ok.
  4. Run the newly added command by the "Run" button right from it (or hit Shift+F10 by default).

Use `RUST_LIB_BACKTRACE` env variable for non panic backtrace verbosity

With the upstream inclusion of Backtrace in std the ecosystem seems to be moving towards using RUST_BACKTRACE for panic based backtraces and RUST_LIB_BACKTRACE for std::backtrace::Backtrace.

I think this will take like 5 minutes to do so I'm gonna open a PR for this one too, in my patched version i just swapped it completely but after thinking abuot it for a sec I think its important to separate the verbosity the same way std does.

hold the stdout lock to detangle multithreaded panics

my naive assumption is that it might not be so much work to take out the stdout lock once before iterating over each item in a backtrace and printing them out as a consistent block.

I cause a ton of concurrent panics where hundreds of lines can sometimes fill the space between the initial panic message and parts of the relevant file information. By taking out the stdout lock just once and holding it until the entire backtrace is completed, I assume it would make these error messages much more consistent.

I'd be happy to investigate farther if you think this would be helpful! Let me know :]

Support for std::backtrace::Backtrace

std::error::Error has an experimental support for providing a backtrace of type std::backtrace::Backtrace. However color-backtrace accepts only types backtrace::Backtrace and failure::Backtrace in its printing functions.

Would it be possible to add support for the std variant as well? I'm not sure how hard it would be, because it doesn't expose its inner frames.

Allow indirect usage

Currently, the crate can only be used as the only, global, panic handler. It would be great if the formatter could be used separately, on a custom writer.

In my case, this prevents me from being able to use this, since I require some custom logic in my panic hook. It'd be awesome if I could make use of this beautiful formatting though!

Consider making `Frame::is_dependency_code` public?

Hi, thanks for the awesome crate, I love it really much.
One issue for me is default backtrace is sometimes too verbosing to me..

And I found Frame provides is_dependency_code method to make output to have different colors.

I think it would be good to have a way to filter frames by is_dependency_code too, it will make backtrace much simpler because I don't need to see something like tokio's backtrace

Currently I can't write something like this:

use color_backtrace::{default_output_stream, BacktracePrinter};
let printer = BacktracePrinter::new();
# it failed because `is_dependency_code` is a private method.
let printer =
     printer.add_frame_filter(Box::new(|frames| frames.retain(|x| !x.is_dependency_code)));
let mut stream = default_output_stream();
let tb = backtrace::Backtrace::new();
let _ = printer.print_trace(&tb, &mut stream);

What do you think?

add support for deserializing and printing `std::backtrace::Backtrace`

The nightly std::backtrace::Backtrace has a debug format that is relatively easy to parse. There are plans to eventually add a frame iterator api to backtrace similar to backtrace-rs's Backtrace but it seems rather far off. Until then I think it makes sense to write a deserializer for the Debug format of backtrace, which should hopefully be pretty stable, and use that to build the Frame objects used internally to print the backtrace.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.