Skip to content

Commit

Permalink
Put message box behind a gui feature
Browse files Browse the repository at this point in the history
  • Loading branch information
rukai committed Jul 12, 2018
1 parent df1ed0d commit 61249ce
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 46 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ winapi = { version = "0.3", features = ["winuser"] }

[features]
nightly = []
gui = []

[workspace]
members = [
"tests/gui-example",
"tests/single-panic",
"tests/custom-panic",
]
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ Rust is pretty great at safety, it's not unheard of to access the wrong index
in a vector or have an assert fail somewhere.

When an error eventually occurs, you probably will want to know about it. So
instead of just providing an error message on the command line or the GUI
suddenly disappearing, we can create a call to action for people to submit a
report.
instead of crashing without notice or printing a confusing error message we
can create a call to action for people to submit a report.

This should empower people to engage in communication, lowering the chances
people might get frustrated. And making it easier to figure out what might be
Expand Down Expand Up @@ -114,7 +113,8 @@ $ cargo add human-panic

GUI applications don't have a terminal to output errors to.
The errors printed to the terminal can optionally be displayed in a message box window.
This is enabled by using a `Metadata` struct with `create_window: true`.
This is enabled with `human-panic = { version = "1.0", features = ["gui"] }` in
your `cargo.toml`.
![Example Image](window_example.png)

## License
Expand Down
48 changes: 12 additions & 36 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
//! in a vector or have an assert fail somewhere.
//!
//! When an error eventually occurs, you probably will want to know about it. So
//! instead of just providing an error message on the command line or the GUI
//! suddenly disappearing, we can create a call to action for people to submit a
//! report.
//! instead of crashing without notice or printing a confusing error message we
//! can create a call to action for people to submit a report.
//!
//! This should empower people to engage in communication, lowering the chances
//! people might get frustrated. And making it easier to figure out what might be
Expand Down Expand Up @@ -44,7 +43,8 @@
//! ## GUI Applications
//! GUI applications don't have a terminal to output errors to.
//! The errors printed to the terminal can optionally be displayed in a message box window.
//! This is enabled by using a `Metadata` struct with `create_window: true`.
//! This is enabled with `human-panic = { version = "1.0", features = ["gui"] }`
//! in your `cargo.toml`.
#![cfg_attr(feature = "nightly", deny(missing_docs))]
#![cfg_attr(feature = "nightly", feature(external_doc))]
Expand All @@ -56,20 +56,9 @@ extern crate failure;
extern crate serde_derive;
extern crate termcolor;

#[cfg(target_os = "windows")]
#[path = "windows_window.rs"]
pub mod window;

#[cfg(target_os = "linux")]
#[path = "linux_window.rs"]
pub mod window;

#[cfg(not(any(target_os = "linux", target_os = "windows")))]
pub mod window {
pub fn create_window(_: String) { }
}

mod report;

use report::{Method, Report};

use std::borrow::Cow;
Expand All @@ -88,8 +77,6 @@ pub struct Metadata {
pub authors: Cow<'static, str>,
/// The URL of the crate's website
pub homepage: Cow<'static, str>,
/// Should an error message window be created. Only implemented for Windows + X11. noop on other platforms
pub create_window: bool,
}

/// `human-panic` initialisation macro
Expand All @@ -110,53 +97,42 @@ pub struct Metadata {
/// version: env!("CARGO_PKG_VERSION").into(),
/// authors: "My Company Support <[email protected]".into(),
/// homepage: "support.mycompany.com".into(),
/// create_window: false,
/// });
/// ```
#[macro_export]
macro_rules! setup_panic {
($meta:expr) => {
use $crate::{handle_dump, print_msg, write_msg, Metadata};
use $crate::window;
use $crate::{handle_dump, Metadata};
use std::panic::{self, PanicInfo};
use std::io::{Cursor, Read};

panic::set_hook(Box::new(move |info: &PanicInfo| {
let file_path = handle_dump(&$meta, info);

print_msg(file_path.clone(), &$meta)
$crate::print_msg(file_path.clone(), &$meta)
.expect("human-panic: printing error message to console failed");

if $meta.create_window {
let mut buffer = Cursor::new(vec!());
write_msg(file_path, &$meta, &mut buffer).expect("human-panic: generating error message for GUI failed: write_msg");
buffer.set_position(0);

let mut message = String::new();
buffer.read_to_string(&mut message).expect("human-panic: generating error message for GUI failed: read_to_string");

window::create_window(message);
}
$crate::window::create_window(file_path, &$meta);
}));
};

() => {
use $crate::{handle_dump, print_msg, Metadata};
use $crate::{handle_dump, Metadata};
use std::panic::{self, PanicInfo};

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(),
create_window: false,
};

panic::set_hook(Box::new(move |info: &PanicInfo| {
let file_path = handle_dump(&meta, info);

print_msg(file_path, &meta)
$crate::print_msg(file_path.clone(), &meta)
.expect("human-panic: printing error message to console failed");

$crate::window::create_window(file_path, &meta);
}));
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/linux_window.rs → src/window/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use self::x11_dl::xlib::XRectangle;

const TEXT_MARGIN: i32 = 10;

pub fn create_window(message: String) {
pub(crate) fn create_window(message: String) {
// window state
let mut window_width = 600;
let mut window_height = 400;
Expand Down
33 changes: 33 additions & 0 deletions src/window/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#[cfg(all(target_os = "windows", feature = "gui"))]
#[path = "windows.rs"]
mod window_impl;

#[cfg(all(target_os = "linux", feature = "gui"))]
#[path = "linux.rs"]
mod window_impl;

#[cfg(not(any(target_os = "linux", target_os = "windows")))]
mod window_impl {
pub(crate) fn create_window(_: String) { }
}

use std::path::Path;
use Metadata;

#[allow(unused)]
pub fn create_window<P: AsRef<Path>>(file_path: Option<P>, meta: &Metadata) {
#[cfg(feature = "gui")]
{
use std::io::{Cursor, Read};
use write_msg;

let mut buffer = Cursor::new(vec!());
write_msg(file_path, meta, &mut buffer).expect("human-panic: generating error message for GUI failed: write_msg");
buffer.set_position(0);

let mut message = String::new();
buffer.read_to_string(&mut message).expect("human-panic: generating error message for GUI failed: read_to_string");

window_impl::create_window(message);
}
}
2 changes: 1 addition & 1 deletion src/windows_window.rs → src/window/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::os::windows::ffi::OsStrExt;
use std::ptr::null_mut;
use self::winapi::um::winuser::{MB_OK, MessageBoxW};

pub fn create_window(message: String) {
pub(crate) fn create_window(message: String) {
let message_wide: Vec<u16> = OsStr::new(message.as_str()).encode_wide().chain(once(0)).collect();
let panic_wide: Vec<u16> = OsStr::new("Panic!").encode_wide().chain(once(0)).collect();
let ret = unsafe { MessageBoxW(null_mut(), message_wide.as_ptr(), panic_wide.as_ptr(), MB_OK) };
Expand Down
1 change: 0 additions & 1 deletion tests/custom-panic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ fn main() {
version: env!("CARGO_PKG_VERSION").into(),
authors: "My Company Support <[email protected]".into(),
homepage: "support.mycompany.com".into(),
create_window: false,
});

println!("A normal log message");
Expand Down
7 changes: 7 additions & 0 deletions tests/gui-example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "custom-panic-gui-example"
version = "0.1.0"
authors = ["Human Panic Authors <[email protected]>"]

[dependencies]
human-panic = { path = "../..", features = ["gui"] }
5 changes: 2 additions & 3 deletions examples/window.rs → tests/gui-example/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![windows_subsystem = "windows"]
#![windows_subsystem = "windows"] // disable the terminal in windows, like a real gui app

#[macro_use]
extern crate human_panic;
Expand All @@ -7,9 +7,8 @@ fn main() {
setup_panic!(Metadata {
name: "Human Panic Window Example".into(),
version: env!("CARGO_PKG_VERSION").into(),
authors: "ルカス".into(),
authors: "ルカス".into(), // Can the GUI handle UTF8?
homepage: "https://github.com/rust-clique/human-panic/issues".into(),
create_window: true,
});
panic!("oh no");
}

0 comments on commit 61249ce

Please sign in to comment.