diff --git a/CHANGELOG.md b/CHANGELOG.md index f064bf99..7613e4fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - log tab refreshes when head changes ([#78](https://github.com/extrawurst/gitui/issues/78)) - performance optimization of the log tab in big repos - more readable default color for the commit hash in the log tab +- more error/panic resiliance (`unwrap`/`panic` denied by clippy now) ### Fixes - panic on small terminal width ([#72](https://github.com/extrawurst/gitui/issues/72)) diff --git a/src/app.rs b/src/app.rs index f5b93b27..279aa66e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,7 +11,7 @@ use crate::{ tabs::{Revlog, Stashing, Status}, ui::style::Theme, }; -use anyhow::Result; +use anyhow::{anyhow, Result}; use asyncgit::{sync, AsyncNotification, CWD}; use crossbeam_channel::Sender; use crossterm::event::Event; @@ -96,7 +96,7 @@ impl App { 0 => self.status_tab.draw(f, chunks_main[1])?, 1 => self.revlog.draw(f, chunks_main[1])?, 2 => self.stashing_tab.draw(f, chunks_main[1])?, - _ => panic!("unknown tab"), + _ => return Err(anyhow!("unknown tab")), }; Self::draw_commands( diff --git a/src/main.rs b/src/main.rs index 348c207a..08d4a463 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,8 @@ #![allow(clippy::cargo::multiple_crate_versions)] #![deny(clippy::pedantic)] #![deny(clippy::result_unwrap_used)] +#![deny(clippy::panic)] #![allow(clippy::module_name_repetitions)] -use anyhow::{anyhow, Result}; mod app; mod components; @@ -20,6 +20,7 @@ mod ui; mod version; use crate::{app::App, poll::QueueEvent}; +use anyhow::{anyhow, Result}; use asyncgit::AsyncNotification; use backtrace::Backtrace; use crossbeam_channel::{tick, unbounded, Receiver, Select}; @@ -30,7 +31,6 @@ use crossterm::{ }, ExecutableCommand, }; -use log::error; use scopeguard::defer; use scopetime::scope_time; use simplelog::{Config, LevelFilter, WriteLogger}; @@ -41,6 +41,7 @@ use std::{ io::{self, Write}, panic, path::PathBuf, + process, time::{Duration, Instant}, }; use tui::{ @@ -177,7 +178,7 @@ fn select_event( 3 => oper .recv(rx_spinner) .map(|_| events.push(QueueEvent::SpinnerUpdate)), - _ => panic!("unknown select source"), + _ => return Err(anyhow!("unknown select source")), }?; Ok(events) @@ -222,17 +223,23 @@ fn set_panic_handlers() -> Result<()> { // regular panic handler panic::set_hook(Box::new(|e| { let backtrace = Backtrace::new(); - error!("panic: {:?}\ntrace:\n{:?}", e, backtrace); + log::error!("panic: {:?}\ntrace:\n{:?}", e, backtrace); shutdown_terminal().expect("shutdown failed inside panic"); eprintln!("panic: {:?}\ntrace:\n{:?}", e, backtrace); })); // global threadpool - Ok(rayon_core::ThreadPoolBuilder::new() + rayon_core::ThreadPoolBuilder::new() .panic_handler(|e| { - error!("thread panic: {:?}", e); - panic!(e) + let backtrace = Backtrace::new(); + log::error!("panic: {:?}\ntrace:\n{:?}", e, backtrace); + shutdown_terminal() + .expect("shutdown failed inside panic"); + eprintln!("panic: {:?}\ntrace:\n{:?}", e, backtrace); + process::abort(); }) .num_threads(4) - .build_global()?) + .build_global()?; + + Ok(()) }