diff --git a/Cargo.toml b/Cargo.toml index 35501b8..d631381 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ edition = "2021" exclude = ["assets/*", ".github/*"] [dependencies] -anyhow = "1.0.75" clap = { version = "4.5.4", features = ["derive", "env", "string"] } clap-markdown = "0.1.3" colored = "2.1.0" @@ -52,6 +51,10 @@ strsim = "0.11.1" scraper = "0.19.0" serde_json = "1.0.117" rhai = "1.18.0" +better-panic = "0.3.0" +color-eyre = "0.6.3" +strip-ansi-escapes = "0.2.0" +human-panic = "2.0.0" # Strip the debug symbols from the binary [profile.release] diff --git a/src/cli/interactive.rs b/src/cli/interactive.rs index c732b1f..9866607 100644 --- a/src/cli/interactive.rs +++ b/src/cli/interactive.rs @@ -3,8 +3,8 @@ use crate::cli::opts::Opts; use crate::utils::tree::tree; use crate::utils::tree::TreeData; use crate::utils::tree::TreeNode; -use anyhow::bail; -use anyhow::Result; +use color_eyre::eyre::bail; +use color_eyre::eyre::Result; use colored::Colorize; use lazy_static::lazy_static; use log::error; diff --git a/src/cli/opts.rs b/src/cli/opts.rs index a7aa1db..a0f0c34 100644 --- a/src/cli/opts.rs +++ b/src/cli/opts.rs @@ -9,7 +9,7 @@ use super::helpers::{ parse_cookie, parse_header, parse_method, parse_url, parse_wordlist, KeyOrKeyVal, KeyOrKeyValParser, KeyVal, KeyValParser, }; -use anyhow::Result; +use color_eyre::eyre::Result; use clap::Parser; use merge::Merge; diff --git a/src/lib.rs b/src/lib.rs index 36f07e2..92d8c75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,8 +19,8 @@ use crate::{ table::build_opts_table, }, }; -use anyhow::bail; -use anyhow::Result; +use color_eyre::eyre::bail; +use color_eyre::eyre::Result; use colored::Colorize; use futures::{future::abortable, FutureExt}; use indicatif::HumanDuration; diff --git a/src/main.rs b/src/main.rs index d967e7e..d8e307c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] -use anyhow::Result; +use color_eyre::eyre::Result; use clap::{CommandFactory, Parser, ValueEnum}; use clap_complete::{generate, Generator, Shell}; use clap_complete_nushell::Nushell; @@ -19,7 +19,8 @@ use std::{fs::OpenOptions, path::Path, process}; #[tokio::main] async fn main() -> Result<()> { utils::logger::init_logger(); - + utils::init_panic()?; + panic!("test"); let mut opts = Opts::parse(); if let Some(p) = opts.config { diff --git a/src/runner/classic.rs b/src/runner/classic.rs index 7ea464c..ae10adb 100644 --- a/src/runner/classic.rs +++ b/src/runner/classic.rs @@ -11,7 +11,7 @@ use crate::{ tree::{Tree, TreeData, UrlType}, }, }; -use anyhow::{anyhow, Result}; +use color_eyre::eyre::{anyhow, Result}; use colored::Colorize; use indicatif::ProgressBar; use itertools::Itertools; diff --git a/src/runner/client.rs b/src/runner/client.rs index 8f9a827..a0d9036 100644 --- a/src/runner/client.rs +++ b/src/runner/client.rs @@ -1,6 +1,6 @@ use std::path::Path; -use anyhow::{Context, Result}; +use color_eyre::eyre::{Context, ContextCompat, Result}; use http_rest_file::{model::Header, Parser}; use reqwest::{ header::{HeaderMap, HeaderName}, diff --git a/src/runner/extract.rs b/src/runner/extract.rs index c63234e..2945cfe 100644 --- a/src/runner/extract.rs +++ b/src/runner/extract.rs @@ -1,4 +1,4 @@ -use anyhow::{Context, Result}; +use color_eyre::eyre::{Context, Result}; use lazy_static::lazy_static; use scraper::{Html, Selector}; use std::fmt; @@ -66,13 +66,13 @@ impl fmt::Display for Link { } pub fn is_same_domain(url: &Url, base: &Url, allow_subdomain: bool) -> Result { - let url_domain = url - .domain() - .ok_or_else(|| anyhow::anyhow!("Could not parse domain from URL: {}", url.to_string()))?; + let url_domain = url.domain().ok_or_else(|| { + color_eyre::eyre::anyhow!("Could not parse domain from URL: {}", url.to_string()) + })?; - let base_domain = base - .domain() - .ok_or_else(|| anyhow::anyhow!("Could not parse domain from URL: {}", base.to_string()))?; + let base_domain = base.domain().ok_or_else(|| { + color_eyre::eyre::anyhow!("Could not parse domain from URL: {}", base.to_string()) + })?; if allow_subdomain { Ok(url_domain == base_domain || url_domain.ends_with(&format!(".{}", base_domain))) diff --git a/src/runner/mod.rs b/src/runner/mod.rs index 0dc0fba..8aa0db2 100644 --- a/src/runner/mod.rs +++ b/src/runner/mod.rs @@ -9,7 +9,7 @@ pub mod wordlists; use std::future::Future; -use anyhow::Result; +use color_eyre::eyre::Result; pub trait Runner { fn run(self) -> impl Future> + Send; diff --git a/src/runner/recursive.rs b/src/runner/recursive.rs index 031e434..a164893 100644 --- a/src/runner/recursive.rs +++ b/src/runner/recursive.rs @@ -8,7 +8,7 @@ use std::{ }; use tokio::task::JoinHandle; -use anyhow::{anyhow, Result}; +use color_eyre::eyre::{anyhow, Result}; use parking_lot::Mutex; use crate::{ diff --git a/src/runner/scripting.rs b/src/runner/scripting.rs index 8b9c90c..4a01902 100644 --- a/src/runner/scripting.rs +++ b/src/runner/scripting.rs @@ -2,7 +2,7 @@ use crate::{ cli::opts::Opts, utils::tree::{tree, TreeData}, }; -use anyhow::{anyhow, Result}; +use color_eyre::eyre::{anyhow, Result}; use colored::Colorize; use indicatif::ProgressBar; diff --git a/src/runner/spider.rs b/src/runner/spider.rs index f14e555..f257959 100644 --- a/src/runner/spider.rs +++ b/src/runner/spider.rs @@ -11,8 +11,8 @@ use crate::{ tree::{Tree, TreeData, UrlType}, }, }; -use anyhow::anyhow; -use anyhow::{Context, Ok, Result}; +use color_eyre::eyre::anyhow; +use color_eyre::eyre::{Context, Ok, Result}; use colored::Colorize; use indicatif::ProgressBar; use itertools::Itertools; diff --git a/src/runner/wordlists.rs b/src/runner/wordlists.rs index a539cb7..5ce0d68 100644 --- a/src/runner/wordlists.rs +++ b/src/runner/wordlists.rs @@ -3,7 +3,7 @@ use std::{ path::{Path, PathBuf}, }; -use anyhow::{Context, Result}; +use color_eyre::eyre::{Context, Result}; use colored::Colorize; use tokio::io::AsyncReadExt; @@ -433,7 +433,7 @@ fn expand_tilde>(path_user_input: P) -> Result { } if p == Path::new("~") { return dirs::home_dir() - .ok_or_else(|| anyhow::anyhow!("Failed to expand tilde in path: {}", p.display())); + .ok_or_else(|| color_eyre::eyre::anyhow!("Failed to expand tilde in path: {}", p.display())); } dirs::home_dir() .map(|mut h| { @@ -446,7 +446,7 @@ fn expand_tilde>(path_user_input: P) -> Result { h } }) - .ok_or_else(|| anyhow::anyhow!("Failed to expand tilde in path: {}", p.display())) + .ok_or_else(|| color_eyre::eyre::anyhow!("Failed to expand tilde in path: {}", p.display())) } #[cfg(test)] diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 790318b..2d1f3c7 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use color_eyre::eyre::{bail, Result}; use colored::{Colorize, CustomColor}; use parking_lot::Mutex; use std::{io::Write, sync::Arc}; @@ -140,6 +140,50 @@ pub fn is_range(s: &str) -> bool { false } +pub fn init_panic() -> Result<()> { + let (panic_hook, eyre_hook) = color_eyre::config::HookBuilder::default() + .panic_section(format!( + "This is a bug. Consider reporting it at {}", + env!("CARGO_PKG_REPOSITORY") + )) + .capture_span_trace_by_default(false) + .display_location_section(false) + .display_env_section(false) + .into_hooks(); + eyre_hook.install()?; + std::panic::set_hook(Box::new(move |panic_info| { + #[cfg(not(debug_assertions))] + { + use human_panic::{handle_dump, print_msg, Metadata}; + + let meta = Metadata::new(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")) + .authors(env!("CARGO_PKG_AUTHORS").replace(':', ", ")) + .homepage(env!("CARGO_PKG_HOMEPAGE")); + + let file_path = handle_dump(&meta, panic_info); + // prints human-panic message + print_msg(file_path, &meta) + .expect("human-panic: printing error message to console failed"); + eprintln!("{}", panic_hook.panic_report(panic_info)); // prints color-eyre stack trace to stderr + } + let msg = format!("{}", panic_hook.panic_report(panic_info)); + log::error!("Error: {}", strip_ansi_escapes::strip_str(msg)); + + #[cfg(debug_assertions)] + { + // Better Panic stacktrace that is only enabled when debugging. + better_panic::Settings::auto() + .most_recent_first(false) + .lineno_suffix(true) + .verbosity(better_panic::Verbosity::Full) + .create_panic_handler()(panic_info); + } + + std::process::exit(1); + })); + Ok(()) +} + // Write the tree to a file (json, csv, md) pub fn save_to_file( opts: &Opts, diff --git a/src/utils/tree.rs b/src/utils/tree.rs index a261b47..eef4dac 100644 --- a/src/utils/tree.rs +++ b/src/utils/tree.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use color_eyre::eyre::Result; use colored::Colorize; use log::{info, warn}; use parking_lot::Mutex; @@ -285,7 +285,7 @@ pub fn from_save( ) -> Result>>> { if let Some(root) = &save.tree.clone().lock().root { if opts.url.is_some() && root.lock().data.url != opts.url.clone().unwrap() { - Err(anyhow::anyhow!( + Err(color_eyre::eyre::anyhow!( "The URL of the saved state does not match the URL provided" )) } else { @@ -306,7 +306,7 @@ pub fn from_save( Ok(save.tree.clone()) } } else { - Err(anyhow::anyhow!("No saved state found")) + Err(color_eyre::eyre::anyhow!("No saved state found")) } } diff --git a/tests/integration.rs b/tests/integration.rs index 8342764..68cfeba 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -1,5 +1,5 @@ -use anyhow::Result; use clap::Parser; +use color_eyre::eyre::Result; use rwalk::{ _main, cli::opts::{Opts, Wordlist},