Repository: eyre-rs/color-eyre (Rust)

Issue:
install call panics instead of returning a result
Currently colored_eyre panics [here](https://github.com/yaahc/color-eyre/blob/07b9f0351544e2b07fcd173dc1fc602a7fc8bb6b/src/config.rs#L736) if you try to install it multiple times. Thus `let _ = color_eyre::install();` won't work when used in tests and the result from install() is kinda meaningless.

<details>
  <summary>panic backtrace</summary>

```text
0: std::panicking::begin_panic_handler
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\std\src\panicking.rs:517
   1: core::panicking::panic_fmt
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\core\src\panicking.rs:101
   2: core::result::unwrap_failed
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\/library\core\src\result.rs:1617
   3: core::result::Result::expect<tuple$<>,color_spantrace::InstallThemeError>
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35\library\core\src\result.rs:1259
   4: color_eyre::config::HookBuilder::into_hooks
             at C:\Users\Aron\.cargo\registry\src\github.com-1ecc6299db9ec823\color-eyre-0.5.11\src\config.rs:736
   5: color_eyre::config::HookBuilder::install
             at C:\Users\Aron\.cargo\registry\src\github.com-1ecc6299db9ec823\color-eyre-0.5.11\src\config.rs:685
   6: color_eyre::install
             at C:\Users\Aron\.cargo\registry\src\github.com-1ecc6299db9ec823\color-eyre-0.5.11\src\lib.rs:459
```

</details>


Discussion:

Patch:
diff --git a/src/config.rs b/src/config.rs
index 40a079c..4f52111 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -4,6 +4,7 @@ use crate::{
     section::PanicMessage,
     writers::{EnvSection, WriterExt},
 };
+use eyre::WrapErr;
 use fmt::Display;
 use indenter::{indented, Format};
 use owo_colors::{style, OwoColorize, Style};
@@ -700,7 +701,7 @@ impl HookBuilder {
 
     /// Install the given Hook as the global error report hook
     pub fn install(self) -> Result<(), crate::eyre::Report> {
-        let (panic_hook, eyre_hook) = self.into_hooks();
+        let (panic_hook, eyre_hook) = self.try_into_hooks()?;
         eyre_hook.install()?;
         panic_hook.install();
         Ok(())
@@ -715,6 +716,12 @@ impl HookBuilder {
     /// Create a `PanicHook` and `EyreHook` from this `HookBuilder`.
     /// This can be used if you want to combine these handlers with other handlers.
     pub fn into_hooks(self) -> (PanicHook, EyreHook) {
+        self.try_into_hooks().expect("into_hooks should only be called when no `color_spantrace` themes have previously been set")
+    }
+
+    /// Create a `PanicHook` and `EyreHook` from this `HookBuilder`.
+    /// This can be used if you want to combine these handlers with other handlers.
+    pub fn try_into_hooks(self) -> Result<(PanicHook, EyreHook), crate::eyre::Report> {
         let theme = self.theme;
         #[cfg(feature = "issue-url")]
         let metadata = Arc::new(self.issue_metadata);
@@ -753,9 +760,9 @@ impl HookBuilder {
         };
 
         #[cfg(feature = "capture-spantrace")]
-        color_spantrace::set_theme(self.theme.into()).expect("could not set the provided `Theme` via `color_spantrace::set_theme` globally as another was already set");
+        color_spantrace::set_theme(self.theme.into()).wrap_err("could not set the provided `Theme` via `color_spantrace::set_theme` globally as another was already set")?;
 
-        (panic_hook, eyre_hook)
+        Ok((panic_hook, eyre_hook))
     }
 }
 


Test patch:
diff --git a/tests/install.rs b/tests/install.rs
new file mode 100644
index 0000000..d5e85b2
--- /dev/null
+++ b/tests/install.rs
@@ -0,0 +1,7 @@
+use color_eyre::install;
+
+#[test]
+fn double_install_should_not_panic() {
+    install().unwrap();
+    assert!(install().is_err());
+}