1 | //! An error report handler for panics and the [`eyre`] crate for colorful, consistent, and well |
2 | //! formatted error reports for all kinds of errors. |
3 | //! |
4 | //! ## TLDR |
5 | //! |
6 | //! `color_eyre` helps you build error reports that look like this: |
7 | //! |
8 | //! <pre><span style="color: #06989A"><b>color-eyre</b></span> on <span style="color: #75507B"><b> hooked</b></span> <span style="color: #CC0000"><b>[$!] </b></span>is <span style="color: #FF8700"><b>📦 v0.5.0</b></span> via <span style="color: #CC0000"><b>🦀 v1.44.0</b></span> |
9 | //! <span style="color: #4E9A06"><b>❯</b></span> cargo run --example custom_section |
10 | //! <span style="color: #4E9A06"><b> Finished</b></span> dev [unoptimized + debuginfo] target(s) in 0.04s |
11 | //! <span style="color: #4E9A06"><b> Running</b></span> `target/debug/examples/custom_section` |
12 | //! Error: |
13 | //! 0: <span style="color: #F15D22">Unable to read config</span> |
14 | //! 1: <span style="color: #F15D22">cmd exited with non-zero status code</span> |
15 | //! |
16 | //! Stderr: |
17 | //! cat: fake_file: No such file or directory |
18 | //! |
19 | //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
20 | //! |
21 | //! 0: <span style="color: #F15D22">custom_section::output2</span> with <span style="color: #34E2E2">self="cat" "fake_file"</span> |
22 | //! at <span style="color: #75507B">examples/custom_section.rs</span>:<span style="color: #75507B">14</span> |
23 | //! 1: <span style="color: #F15D22">custom_section::read_file</span> with <span style="color: #34E2E2">path="fake_file"</span> |
24 | //! at <span style="color: #75507B">examples/custom_section.rs</span>:<span style="color: #75507B">58</span> |
25 | //! 2: <span style="color: #F15D22">custom_section::read_config</span> |
26 | //! at <span style="color: #75507B">examples/custom_section.rs</span>:<span style="color: #75507B">63</span> |
27 | //! |
28 | //! <span style="color: #34E2E2">Suggestion</span>: try using a file that exists next time</pre> |
29 | //! |
30 | //! ## Setup |
31 | //! |
32 | //! Add the following to your toml file: |
33 | //! |
34 | //! ```toml |
35 | //! [dependencies] |
36 | //! color-eyre = "0.5" |
37 | //! ``` |
38 | //! |
39 | //! And install the panic and error report handlers: |
40 | //! |
41 | //! ```rust |
42 | //! use color_eyre::eyre::Result; |
43 | //! |
44 | //! fn main() -> Result<()> { |
45 | //! color_eyre::install()?; |
46 | //! |
47 | //! // ... |
48 | //! # Ok(()) |
49 | //! } |
50 | //! ``` |
51 | //! |
52 | //! ### Disabling tracing support |
53 | //! |
54 | //! If you don't plan on using `tracing_error` and `SpanTrace` you can disable the |
55 | //! tracing integration to cut down on unused dependencies: |
56 | //! |
57 | //! ```toml |
58 | //! [dependencies] |
59 | //! color-eyre = { version = "0.5", default-features = false } |
60 | //! ``` |
61 | //! |
62 | //! ### Disabling SpanTrace capture by default |
63 | //! |
64 | //! color-eyre defaults to capturing span traces. This is because `SpanTrace` |
65 | //! capture is significantly cheaper than `Backtrace` capture. However, like |
66 | //! backtraces, span traces are most useful for debugging applications, and it's |
67 | //! not uncommon to want to disable span trace capture by default to keep noise out |
68 | //! developer. |
69 | //! |
70 | //! To disable span trace capture you must explicitly set one of the env variables |
71 | //! that regulate `SpanTrace` capture to `"0"`: |
72 | //! |
73 | //! ```rust |
74 | //! if std::env::var("RUST_SPANTRACE" ).is_err() { |
75 | //! std::env::set_var("RUST_SPANTRACE" , "0" ); |
76 | //! } |
77 | //! ``` |
78 | //! |
79 | //! ### Improving perf on debug builds |
80 | //! |
81 | //! In debug mode `color-eyre` behaves noticably worse than `eyre`. This is caused |
82 | //! by the fact that `eyre` uses `std::backtrace::Backtrace` instead of |
83 | //! `backtrace::Backtrace`. The std version of backtrace is precompiled with |
84 | //! optimizations, this means that whether or not you're in debug mode doesn't |
85 | //! matter much for how expensive backtrace capture is, it will always be in the |
86 | //! 10s of milliseconds to capture. A debug version of `backtrace::Backtrace` |
87 | //! however isn't so lucky, and can take an order of magnitude more time to capture |
88 | //! a backtrace compared to its std counterpart. |
89 | //! |
90 | //! Cargo [profile |
91 | //! overrides](https://doc.rust-lang.org/cargo/reference/profiles.html#overrides) |
92 | //! can be used to mitigate this problem. By configuring your project to always |
93 | //! build `backtrace` with optimizations you should get the same performance from |
94 | //! `color-eyre` that you're used to with `eyre`. To do so add the following to |
95 | //! your Cargo.toml: |
96 | //! |
97 | //! ```toml |
98 | //! [profile.dev.package.backtrace] |
99 | //! opt-level = 3 |
100 | //! ``` |
101 | //! |
102 | //! ## Features |
103 | //! |
104 | //! ### Multiple report format verbosity levels |
105 | //! |
106 | //! `color-eyre` provides 3 different report formats for how it formats the captured `SpanTrace` |
107 | //! and `Backtrace`, minimal, short, and full. Take the below snippets of the output produced by [`examples/usage.rs`]: |
108 | //! |
109 | //! --- |
110 | //! |
111 | //! Running `cargo run --example usage` without `RUST_LIB_BACKTRACE` set will produce a minimal |
112 | //! report like this: |
113 | //! |
114 | //! <pre><span style="color: #06989A"><b>color-eyre</b></span> on <span style="color: #75507B"><b> hooked</b></span> <span style="color: #CC0000"><b>[$!] </b></span>is <span style="color: #FF8700"><b>📦 v0.5.0</b></span> via <span style="color: #CC0000"><b>🦀 v1.44.0</b></span> took <span style="color: #C4A000"><b>2s</b></span> |
115 | //! <span style="color: #CC0000"><b>❯</b></span> cargo run --example usage |
116 | //! <span style="color: #4E9A06"><b> Finished</b></span> dev [unoptimized + debuginfo] target(s) in 0.04s |
117 | //! <span style="color: #4E9A06"><b> Running</b></span> `target/debug/examples/usage` |
118 | //! <span style="color: #A1A1A1">Jul 05 19:15:58.026 </span><span style="color: #4E9A06"> INFO</span> <b>read_config</b>:<b>read_file{</b>path="fake_file"<b>}</b>: Reading file |
119 | //! Error: |
120 | //! 0: <span style="color: #F15D22">Unable to read config</span> |
121 | //! 1: <span style="color: #F15D22">No such file or directory (os error 2)</span> |
122 | //! |
123 | //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
124 | //! |
125 | //! 0: <span style="color: #F15D22">usage::read_file</span> with <span style="color: #34E2E2">path="fake_file"</span> |
126 | //! at <span style="color: #75507B">examples/usage.rs</span>:<span style="color: #75507B">32</span> |
127 | //! 1: <span style="color: #F15D22">usage::read_config</span> |
128 | //! at <span style="color: #75507B">examples/usage.rs</span>:<span style="color: #75507B">38</span> |
129 | //! |
130 | //! <span style="color: #34E2E2">Suggestion</span>: try using a file that exists next time</pre> |
131 | //! |
132 | //! <br> |
133 | //! |
134 | //! Running `RUST_LIB_BACKTRACE=1 cargo run --example usage` tells `color-eyre` to use the short |
135 | //! format, which additionally capture a [`backtrace::Backtrace`]: |
136 | //! |
137 | //! <pre><span style="color: #06989A"><b>color-eyre</b></span> on <span style="color: #75507B"><b> hooked</b></span> <span style="color: #CC0000"><b>[$!] </b></span>is <span style="color: #FF8700"><b>📦 v0.5.0</b></span> via <span style="color: #CC0000"><b>🦀 v1.44.0</b></span> |
138 | //! <span style="color: #CC0000"><b>❯</b></span> RUST_LIB_BACKTRACE=1 cargo run --example usage |
139 | //! <span style="color: #4E9A06"><b> Finished</b></span> dev [unoptimized + debuginfo] target(s) in 0.04s |
140 | //! <span style="color: #4E9A06"><b> Running</b></span> `target/debug/examples/usage` |
141 | //! <span style="color: #A1A1A1">Jul 05 19:16:02.853 </span><span style="color: #4E9A06"> INFO</span> <b>read_config</b>:<b>read_file{</b>path="fake_file"<b>}</b>: Reading file |
142 | //! Error: |
143 | //! 0: <span style="color: #F15D22">Unable to read config</span> |
144 | //! 1: <span style="color: #F15D22">No such file or directory (os error 2)</span> |
145 | //! |
146 | //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
147 | //! |
148 | //! 0: <span style="color: #F15D22">usage::read_file</span> with <span style="color: #34E2E2">path="fake_file"</span> |
149 | //! at <span style="color: #75507B">examples/usage.rs</span>:<span style="color: #75507B">32</span> |
150 | //! 1: <span style="color: #F15D22">usage::read_config</span> |
151 | //! at <span style="color: #75507B">examples/usage.rs</span>:<span style="color: #75507B">38</span> |
152 | //! |
153 | //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
154 | //! <span style="color: #34E2E2"> ⋮ 5 frames hidden ⋮ </span> |
155 | //! 6: <span style="color: #F15D22">usage::read_file</span><span style="color: #88807C">::haee210cb22460af3</span> |
156 | //! at <span style="color: #75507B">/home/jlusby/git/yaahc/color-eyre/examples/usage.rs</span>:<span style="color: #75507B">35</span> |
157 | //! 7: <span style="color: #F15D22">usage::read_config</span><span style="color: #88807C">::ha649ef4ec333524d</span> |
158 | //! at <span style="color: #75507B">/home/jlusby/git/yaahc/color-eyre/examples/usage.rs</span>:<span style="color: #75507B">40</span> |
159 | //! 8: <span style="color: #F15D22">usage::main</span><span style="color: #88807C">::hbe443b50eac38236</span> |
160 | //! at <span style="color: #75507B">/home/jlusby/git/yaahc/color-eyre/examples/usage.rs</span>:<span style="color: #75507B">11</span> |
161 | //! <span style="color: #34E2E2"> ⋮ 10 frames hidden ⋮ </span> |
162 | //! |
163 | //! <span style="color: #34E2E2">Suggestion</span>: try using a file that exists next time</pre> |
164 | //! |
165 | //! <br> |
166 | //! |
167 | //! Finally, running `RUST_LIB_BACKTRACE=full cargo run --example usage` tells `color-eyre` to use |
168 | //! the full format, which in addition to the above will attempt to include source lines where the |
169 | //! error originated from, assuming it can find them on the disk. |
170 | //! |
171 | //! <pre><span style="color: #06989A"><b>color-eyre</b></span> on <span style="color: #75507B"><b> hooked</b></span> <span style="color: #CC0000"><b>[$!] </b></span>is <span style="color: #FF8700"><b>📦 v0.5.0</b></span> via <span style="color: #CC0000"><b>🦀 v1.44.0</b></span> |
172 | //! <span style="color: #CC0000"><b>❯</b></span> RUST_LIB_BACKTRACE=full cargo run --example usage |
173 | //! <span style="color: #4E9A06"><b> Finished</b></span> dev [unoptimized + debuginfo] target(s) in 0.05s |
174 | //! <span style="color: #4E9A06"><b> Running</b></span> `target/debug/examples/usage` |
175 | //! <span style="color: #A1A1A1">Jul 05 19:16:06.335 </span><span style="color: #4E9A06"> INFO</span> <b>read_config</b>:<b>read_file{</b>path="fake_file"<b>}</b>: Reading file |
176 | //! Error: |
177 | //! 0: <span style="color: #F15D22">Unable to read config</span> |
178 | //! 1: <span style="color: #F15D22">No such file or directory (os error 2)</span> |
179 | //! |
180 | //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
181 | //! |
182 | //! 0: <span style="color: #F15D22">usage::read_file</span> with <span style="color: #34E2E2">path="fake_file"</span> |
183 | //! at <span style="color: #75507B">examples/usage.rs</span>:<span style="color: #75507B">32</span> |
184 | //! 30 │ } |
185 | //! 31 │ |
186 | //! <b> 32 > #[instrument]</b> |
187 | //! 33 │ fn read_file(path: &str) -> Result<(), Report> { |
188 | //! 34 │ info!("Reading file"); |
189 | //! 1: <span style="color: #F15D22">usage::read_config</span> |
190 | //! at <span style="color: #75507B">examples/usage.rs</span>:<span style="color: #75507B">38</span> |
191 | //! 36 │ } |
192 | //! 37 │ |
193 | //! <b> 38 > #[instrument]</b> |
194 | //! 39 │ fn read_config() -> Result<(), Report> { |
195 | //! 40 │ read_file("fake_file") |
196 | //! |
197 | //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
198 | //! <span style="color: #34E2E2"> ⋮ 5 frames hidden ⋮ </span> |
199 | //! 6: <span style="color: #F15D22">usage::read_file</span><span style="color: #88807C">::haee210cb22460af3</span> |
200 | //! at <span style="color: #75507B">/home/jlusby/git/yaahc/color-eyre/examples/usage.rs</span>:<span style="color: #75507B">35</span> |
201 | //! 33 │ fn read_file(path: &str) -> Result<(), Report> { |
202 | //! 34 │ info!("Reading file"); |
203 | //! <span style="color: #D3D7CF"><b> 35 > Ok(std::fs::read_to_string(path).map(drop)?)</b></span> |
204 | //! 36 │ } |
205 | //! 37 │ |
206 | //! 7: <span style="color: #F15D22">usage::read_config</span><span style="color: #88807C">::ha649ef4ec333524d</span> |
207 | //! at <span style="color: #75507B">/home/jlusby/git/yaahc/color-eyre/examples/usage.rs</span>:<span style="color: #75507B">40</span> |
208 | //! 38 │ #[instrument] |
209 | //! 39 │ fn read_config() -> Result<(), Report> { |
210 | //! <span style="color: #D3D7CF"><b> 40 > read_file("fake_file")</b></span> |
211 | //! 41 │ .wrap_err("Unable to read config") |
212 | //! 42 │ .suggestion("try using a file that exists next time") |
213 | //! 8: <span style="color: #F15D22">usage::main</span><span style="color: #88807C">::hbe443b50eac38236</span> |
214 | //! at <span style="color: #75507B">/home/jlusby/git/yaahc/color-eyre/examples/usage.rs</span>:<span style="color: #75507B">11</span> |
215 | //! 9 │ color_eyre::install()?; |
216 | //! 10 │ |
217 | //! <span style="color: #D3D7CF"><b> 11 > Ok(read_config()?)</b></span> |
218 | //! 12 │ } |
219 | //! 13 │ |
220 | //! <span style="color: #34E2E2"> ⋮ 10 frames hidden ⋮ </span> |
221 | //! |
222 | //! <span style="color: #34E2E2">Suggestion</span>: try using a file that exists next time</pre> |
223 | //! |
224 | //! ### Custom `Section`s for error reports via [`Section`] trait |
225 | //! |
226 | //! The `section` module provides helpers for adding extra sections to error |
227 | //! reports. Sections are disinct from error messages and are displayed |
228 | //! independently from the chain of errors. Take this example of adding sections |
229 | //! to contain `stderr` and `stdout` from a failed command, taken from |
230 | //! [`examples/custom_section.rs`]: |
231 | //! |
232 | //! ```rust |
233 | //! use color_eyre::{eyre::eyre, SectionExt, Section, eyre::Report}; |
234 | //! use std::process::Command; |
235 | //! use tracing::instrument; |
236 | //! |
237 | //! trait Output { |
238 | //! fn output2(&mut self) -> Result<String, Report>; |
239 | //! } |
240 | //! |
241 | //! impl Output for Command { |
242 | //! #[instrument] |
243 | //! fn output2(&mut self) -> Result<String, Report> { |
244 | //! let output = self.output()?; |
245 | //! |
246 | //! let stdout = String::from_utf8_lossy(&output.stdout); |
247 | //! |
248 | //! if !output.status.success() { |
249 | //! let stderr = String::from_utf8_lossy(&output.stderr); |
250 | //! Err(eyre!("cmd exited with non-zero status code" )) |
251 | //! .with_section(move || stdout.trim().to_string().header("Stdout:" )) |
252 | //! .with_section(move || stderr.trim().to_string().header("Stderr:" )) |
253 | //! } else { |
254 | //! Ok(stdout.into()) |
255 | //! } |
256 | //! } |
257 | //! } |
258 | //! ``` |
259 | //! |
260 | //! --- |
261 | //! |
262 | //! Here we have an function that, if the command exits unsuccessfully, creates a |
263 | //! report indicating the failure and attaches two sections, one for `stdout` and |
264 | //! one for `stderr`. |
265 | //! |
266 | //! Running `cargo run --example custom_section` shows us how these sections are |
267 | //! included in the output: |
268 | //! |
269 | //! <pre><span style="color: #06989A"><b>color-eyre</b></span> on <span style="color: #75507B"><b> hooked</b></span> <span style="color: #CC0000"><b>[$!] </b></span>is <span style="color: #FF8700"><b>📦 v0.5.0</b></span> via <span style="color: #CC0000"><b>🦀 v1.44.0</b></span> took <span style="color: #C4A000"><b>2s</b></span> |
270 | //! <span style="color: #CC0000"><b>❯</b></span> cargo run --example custom_section |
271 | //! <span style="color: #4E9A06"><b> Finished</b></span> dev [unoptimized + debuginfo] target(s) in 0.04s |
272 | //! <span style="color: #4E9A06"><b> Running</b></span> `target/debug/examples/custom_section` |
273 | //! Error: |
274 | //! 0: <span style="color: #F15D22">Unable to read config</span> |
275 | //! 1: <span style="color: #F15D22">cmd exited with non-zero status code</span> |
276 | //! |
277 | //! Stderr: |
278 | //! cat: fake_file: No such file or directory |
279 | //! |
280 | //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
281 | //! |
282 | //! 0: <span style="color: #F15D22">custom_section::output2</span> with <span style="color: #34E2E2">self="cat" "fake_file"</span> |
283 | //! at <span style="color: #75507B">examples/custom_section.rs</span>:<span style="color: #75507B">14</span> |
284 | //! 1: <span style="color: #F15D22">custom_section::read_file</span> with <span style="color: #34E2E2">path="fake_file"</span> |
285 | //! at <span style="color: #75507B">examples/custom_section.rs</span>:<span style="color: #75507B">58</span> |
286 | //! 2: <span style="color: #F15D22">custom_section::read_config</span> |
287 | //! at <span style="color: #75507B">examples/custom_section.rs</span>:<span style="color: #75507B">63</span> |
288 | //! |
289 | //! <span style="color: #34E2E2">Suggestion</span>: try using a file that exists next time</pre> |
290 | //! |
291 | //! Only the `Stderr:` section actually gets included. The `cat` command fails, |
292 | //! so stdout ends up being empty and is skipped in the final report. This gives |
293 | //! us a short and concise error report indicating exactly what was attempted and |
294 | //! how it failed. |
295 | //! |
296 | //! ### Aggregating multiple errors into one report |
297 | //! |
298 | //! It's not uncommon for programs like batched task runners or parsers to want |
299 | //! to return an error with multiple sources. The current version of the error |
300 | //! trait does not support this use case very well, though there is [work being |
301 | //! done](https://github.com/rust-lang/rfcs/pull/2895) to improve this. |
302 | //! |
303 | //! For now however one way to work around this is to compose errors outside the |
304 | //! error trait. `color-eyre` supports such composition in its error reports via |
305 | //! the `Section` trait. |
306 | //! |
307 | //! For an example of how to aggregate errors check out [`examples/multiple_errors.rs`]. |
308 | //! |
309 | //! ### Custom configuration for `color-backtrace` for setting custom filters and more |
310 | //! |
311 | //! The pretty printing for backtraces and span traces isn't actually provided by |
312 | //! `color-eyre`, but instead comes from its dependencies [`color-backtrace`] and |
313 | //! [`color-spantrace`]. `color-backtrace` in particular has many more features |
314 | //! than are exported by `color-eyre`, such as customized color schemes, panic |
315 | //! hooks, and custom frame filters. The custom frame filters are particularly |
316 | //! useful when combined with `color-eyre`, so to enable their usage we provide |
317 | //! the `install` fn for setting up a custom `BacktracePrinter` with custom |
318 | //! filters installed. |
319 | //! |
320 | //! For an example of how to setup custom filters, check out [`examples/custom_filter.rs`]. |
321 | //! |
322 | //! [`eyre`]: https://docs.rs/eyre |
323 | //! [`tracing-error`]: https://docs.rs/tracing-error |
324 | //! [`color-backtrace`]: https://docs.rs/color-backtrace |
325 | //! [`eyre::EyreHandler`]: https://docs.rs/eyre/*/eyre/trait.EyreHandler.html |
326 | //! [`backtrace::Backtrace`]: https://docs.rs/backtrace/*/backtrace/struct.Backtrace.html |
327 | //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html |
328 | //! [`color-spantrace`]: https://github.com/yaahc/color-spantrace |
329 | //! [`Section`]: https://docs.rs/color-eyre/*/color_eyre/trait.Section.html |
330 | //! [`eyre::Report`]: https://docs.rs/eyre/*/eyre/struct.Report.html |
331 | //! [`eyre::Result`]: https://docs.rs/eyre/*/eyre/type.Result.html |
332 | //! [`Handler`]: https://docs.rs/color-eyre/*/color_eyre/struct.Handler.html |
333 | //! [`examples/usage.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/usage.rs |
334 | //! [`examples/custom_filter.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/custom_filter.rs |
335 | //! [`examples/custom_section.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/custom_section.rs |
336 | //! [`examples/multiple_errors.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/multiple_errors.rs |
337 | #![doc (html_root_url = "https://docs.rs/color-eyre/0.6.2" )] |
338 | #![cfg_attr (docsrs, feature(doc_cfg))] |
339 | #![warn ( |
340 | missing_docs, |
341 | rustdoc::missing_doc_code_examples, |
342 | rust_2018_idioms, |
343 | unreachable_pub, |
344 | bad_style, |
345 | const_err, |
346 | dead_code, |
347 | improper_ctypes, |
348 | non_shorthand_field_patterns, |
349 | no_mangle_generic_items, |
350 | overflowing_literals, |
351 | path_statements, |
352 | patterns_in_fns_without_body, |
353 | private_in_public, |
354 | unconditional_recursion, |
355 | unused, |
356 | unused_allocation, |
357 | unused_comparisons, |
358 | unused_parens, |
359 | while_true |
360 | )] |
361 | #![allow (clippy::try_err)] |
362 | |
363 | use std::sync::Arc; |
364 | |
365 | use backtrace::Backtrace; |
366 | pub use eyre; |
367 | #[doc (hidden)] |
368 | pub use eyre::Report; |
369 | #[doc (hidden)] |
370 | pub use eyre::Result; |
371 | pub use owo_colors; |
372 | use section::help::HelpInfo; |
373 | #[doc (hidden)] |
374 | pub use section::Section as Help; |
375 | pub use section::{IndentedSection, Section, SectionExt}; |
376 | #[cfg (feature = "capture-spantrace" )] |
377 | use tracing_error::SpanTrace; |
378 | #[doc (hidden)] |
379 | pub use Handler as Context; |
380 | |
381 | pub mod config; |
382 | mod fmt; |
383 | mod handler; |
384 | pub(crate) mod private; |
385 | pub mod section; |
386 | mod writers; |
387 | |
388 | /// A custom handler type for [`eyre::Report`] which provides colorful error |
389 | /// reports and [`tracing-error`] support. |
390 | /// |
391 | /// # Details |
392 | /// |
393 | /// This type is not intended to be used directly, prefer using it via the |
394 | /// [`color_eyre::Report`] and [`color_eyre::Result`] type aliases. |
395 | /// |
396 | /// [`eyre::Report`]: https://docs.rs/eyre/*/eyre/struct.Report.html |
397 | /// [`tracing-error`]: https://docs.rs/tracing-error |
398 | /// [`color_eyre::Report`]: type.Report.html |
399 | /// [`color_eyre::Result`]: type.Result.html |
400 | pub struct Handler { |
401 | filters: Arc<[Box<config::FilterCallback>]>, |
402 | backtrace: Option<Backtrace>, |
403 | #[cfg (feature = "capture-spantrace" )] |
404 | span_trace: Option<SpanTrace>, |
405 | sections: Vec<HelpInfo>, |
406 | display_env_section: bool, |
407 | #[cfg (feature = "track-caller" )] |
408 | display_location_section: bool, |
409 | #[cfg (feature = "issue-url" )] |
410 | issue_url: Option<String>, |
411 | #[cfg (feature = "issue-url" )] |
412 | issue_metadata: |
413 | std::sync::Arc<Vec<(String, Box<dyn std::fmt::Display + Send + Sync + 'static>)>>, |
414 | #[cfg (feature = "issue-url" )] |
415 | issue_filter: std::sync::Arc<config::IssueFilterCallback>, |
416 | theme: crate::config::Theme, |
417 | #[cfg (feature = "track-caller" )] |
418 | location: Option<&'static std::panic::Location<'static>>, |
419 | } |
420 | |
421 | /// The kind of type erased error being reported |
422 | #[cfg (feature = "issue-url" )] |
423 | #[cfg_attr (docsrs, doc(cfg(feature = "issue-url" )))] |
424 | pub enum ErrorKind<'a> { |
425 | /// A non recoverable error aka `panic!` |
426 | NonRecoverable(&'a dyn std::any::Any), |
427 | /// A recoverable error aka `impl std::error::Error` |
428 | Recoverable(&'a (dyn std::error::Error + 'static)), |
429 | } |
430 | |
431 | /// Install the default panic and error report hooks |
432 | /// |
433 | /// # Details |
434 | /// |
435 | /// This function must be called to enable the customization of `eyre::Report` |
436 | /// provided by `color-eyre`. This function should be called early, ideally |
437 | /// before any errors could be encountered. |
438 | /// |
439 | /// Only the first install will succeed. Calling this function after another |
440 | /// report handler has been installed will cause an error. **Note**: This |
441 | /// function _must_ be called before any `eyre::Report`s are constructed to |
442 | /// prevent the default handler from being installed. |
443 | /// |
444 | /// Installing a global theme in `color_spantrace` manually (by calling |
445 | /// `color_spantrace::set_theme` or `color_spantrace::colorize` before |
446 | /// `install` is called) will result in an error if this function is called. |
447 | /// |
448 | /// # Examples |
449 | /// |
450 | /// ```rust |
451 | /// use color_eyre::eyre::Result; |
452 | /// |
453 | /// fn main() -> Result<()> { |
454 | /// color_eyre::install()?; |
455 | /// |
456 | /// // ... |
457 | /// # Ok(()) |
458 | /// } |
459 | /// ``` |
460 | pub fn install() -> Result<(), crate::eyre::Report> { |
461 | config::HookBuilder::default().install() |
462 | } |
463 | |