Repository: rust-cli/human-panic (language: rust)

Issue:
🙋 Option to print the report
While on desktop applications it makes sense to store the crash report in a file, on mobile devices it can be challenging to actually find the report file, especially for end users. So for these cases I would like to print the whole report, after message, such that it is easier to report.  Is this sth you would consider? Alternatively having a hook to customize the file writing would likely solve this issue as well. Thank you


Discussion / hints:
Maybe not ideal, but you could get the filename via handle_dump, and then read it and display it to the user.

Another option is to use code similar to https://github.com/rust-cli/human-panic/issues/55#issuecomment-473926139 and not use human_panic. Instead of logging to a file you just build and use the string. Then you can actually get the panic message as well.

For reference, this is code I'm using in my own project:
```rust
use std::panic::{self, PanicInfo};

use backtrace::Backtrace;

pub fn setup() {
  panic::set_hook(Box::new(move |info: &PanicInfo| {
    let mut msg = String::new();

    let os = if cfg!(target_os = "windows") {
      "Windows"
    } else if cfg!(target_os = "linux") {
      "Linux"
    } else if cfg!(target_os = "macos") {
      "Mac OS"
    } else if cfg!(target_os = "android") {
      "Android"
    } else {
      "Unknown"
    };

    msg.push_str(&format!("Name: {}\n", env!("CARGO_PKG_NAME")));
    msg.push_str(&format!("Version: {}\n", env!("CARGO_PKG_VERSION")));
    msg.push_str(&format!("Operating System: {}\n", os));

    if let Some(inner) = info.payload().downcast_ref::<&str>() {
      msg.push_str(&format!("Cause: {}.\n", &inner));
    }

    match info.location() {
      Some(location) => msg.push_str(&format!(
        "Location: in file '{}' at line {}\n",
        location.file(),
        location.line()
      )),
      None => msg.push_str("Panic location unknown.\n"),
    };

    msg.push_str(&format!("Message: {}\n", info));

    msg.push_str(&format!("\n{:#?}\n", Backtrace::new()));

    // Do something with msg...
  }));
}
```
thanks @kdar this is really helpful, will try this out

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0095303..2e6cef8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 ### Fixes
 
 - Use normal panics when `RUST_BACKTRACE` is enabled
-- Skip unnecesary frames in backtrace
+- Skip unnecessary frames in backtrace
 
 ## 2018-04-18, Version 0.3.0
 
diff --git a/src/lib.rs b/src/lib.rs
index 0f2a1ab..f3a7a23 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -52,6 +52,8 @@ use std::panic::PanicInfo;
 use std::path::{Path, PathBuf};
 
 /// A convenient metadata struct that describes a crate
+///
+/// See [`metadata!`]
 pub struct Metadata {
   /// The crate version
   pub version: Cow<'static, str>,
@@ -63,6 +65,19 @@ pub struct Metadata {
   pub homepage: Cow<'static, str>,
 }
 
+/// Initialize [`Metadata`]
+#[macro_export]
+macro_rules! metadata {
+  () => {
+    Metadata {
+      version: env!("CARGO_PKG_VERSION").into(),
+      name: env!("CARGO_PKG_NAME").into(),
+      authors: env!("CARGO_PKG_AUTHORS").replace(":", ", ").into(),
+      homepage: env!("CARGO_PKG_HOMEPAGE").into(),
+    }
+  };
+}
+
 /// `human-panic` initialisation macro
 ///
 /// You can either call this macro with no arguments `setup_panic!()` or
@@ -90,44 +105,45 @@ macro_rules! setup_panic {
     #[allow(unused_imports)]
     use $crate::{handle_dump, print_msg, Metadata};
 
-    #[cfg(not(debug_assertions))]
-    match ::std::env::var("RUST_BACKTRACE") {
-      Err(_) => {
+    match $crate::PanicStyle::default() {
+      $crate::PanicStyle::Debug => {}
+      $crate::PanicStyle::Human => {
+        let meta = $meta;
+
         panic::set_hook(Box::new(move |info: &PanicInfo| {
-          let file_path = handle_dump(&$meta, info);
-          print_msg(file_path, &$meta)
+          let file_path = handle_dump(&meta, info);
+          print_msg(file_path, &meta)
             .expect("human-panic: printing error message to console failed");
         }));
       }
-      Ok(_) => {}
     }
   };
 
   () => {
-    #[allow(unused_imports)]
-    use std::panic::{self, PanicInfo};
-    #[allow(unused_imports)]
-    use $crate::{handle_dump, print_msg, Metadata};
+    $crate::setup_panic!($crate::metadata!());
+  };
+}
 
-    #[cfg(not(debug_assertions))]
-    match ::std::env::var("RUST_BACKTRACE") {
-      Err(_) => {
-        let meta = Metadata {
-          version: env!("CARGO_PKG_VERSION").into(),
-          name: env!("CARGO_PKG_NAME").into(),
-          authors: env!("CARGO_PKG_AUTHORS").replace(":", ", ").into(),
-          homepage: env!("CARGO_PKG_HOMEPAGE").into(),
-        };
+/// Style of panic to be used
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum PanicStyle {
+  /// Normal panic
+  Debug,
+  /// Human-formatted panic
+  Human,
+}
 
-        panic::set_hook(Box::new(move |info: &PanicInfo| {
-          let file_path = handle_dump(&meta, info);
-          print_msg(file_path, &meta)
-            .expect("human-panic: printing error message to console failed");
-        }));
+impl Default for PanicStyle {
+  fn default() -> Self {
+    if cfg!(debug_assertions) {
+      PanicStyle::Debug
+    } else {
+      match ::std::env::var("RUST_BACKTRACE") {
+        Ok(_) => PanicStyle::Debug,
+        Err(_) => PanicStyle::Human,
       }
-      Ok(_) => {}
     }
-  };
+  }
 }
 
 /// Utility function that prints a message to our human users


Test patch: