mirror of https://github.com/bobwen-dev/hunter
add back backtraces to commonly logged errors and fix their cause
This commit is contained in:
parent
99980ace6c
commit
9b463b3435
66
src/fail.rs
66
src/fail.rs
|
@ -7,16 +7,28 @@ use async_value::AError;
|
||||||
use termion::event::Key;
|
use termion::event::Key;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Mutex;
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::foldview::LogEntry;
|
use crate::foldview::LogEntry;
|
||||||
|
|
||||||
pub type HResult<T> = Result<T, HError>;
|
pub type HResult<T> = Result<T, HError>;
|
||||||
|
|
||||||
|
pub type Backtrace = Arc<failure::Backtrace>;
|
||||||
|
|
||||||
|
pub trait ArcBacktrace {
|
||||||
|
fn new_arced() -> Backtrace;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArcBacktrace for Backtrace {
|
||||||
|
fn new_arced() -> Backtrace {
|
||||||
|
Arc::new(failure::Backtrace::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Fail, Debug, Clone)]
|
#[derive(Fail, Debug, Clone)]
|
||||||
pub enum HError {
|
pub enum HError {
|
||||||
#[fail(display = "IO error: {} ", _0)]
|
#[fail(display = "IO error: {} ", _0)]
|
||||||
IoError(String),
|
IoError(String, Backtrace),
|
||||||
#[fail(display = "Mutex failed")]
|
#[fail(display = "Mutex failed")]
|
||||||
MutexError,
|
MutexError,
|
||||||
#[fail(display = "Can't lock!")]
|
#[fail(display = "Can't lock!")]
|
||||||
|
@ -34,23 +46,11 @@ pub enum HError {
|
||||||
#[fail(display = "Accessed stale value")]
|
#[fail(display = "Accessed stale value")]
|
||||||
StaleError,
|
StaleError,
|
||||||
#[fail(display = "Failed: {}", _0)]
|
#[fail(display = "Failed: {}", _0)]
|
||||||
Error(String),
|
Error(String, Backtrace),
|
||||||
#[fail(display = "Was None!")]
|
#[fail(display = "Was None!")]
|
||||||
NoneError,
|
NoneError(Backtrace),
|
||||||
#[fail(display = "Not ready yet!")]
|
|
||||||
WillBeNotReady,
|
|
||||||
#[fail(display = "Not ready yet!")]
|
|
||||||
AsyncNotReadyError,
|
|
||||||
#[fail(display = "Async is stale!")]
|
|
||||||
AsyncStaleError,
|
|
||||||
#[fail(display = "Value has already been taken!")]
|
|
||||||
AsyncAlreadyTakenError,
|
|
||||||
#[fail(display = "Async has already been started!")]
|
|
||||||
AsyncAlreadyStartedError,
|
|
||||||
#[fail(display = "Async Error: {}", _0)]
|
#[fail(display = "Async Error: {}", _0)]
|
||||||
AsyncError(String),
|
AError(async_value::AError, Backtrace),
|
||||||
#[fail(display = "Async Error: {}", _0)]
|
|
||||||
AError(async_value::AError),
|
|
||||||
#[fail(display = "No widget found")]
|
#[fail(display = "No widget found")]
|
||||||
NoWidgetError,
|
NoWidgetError,
|
||||||
#[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)]
|
#[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)]
|
||||||
|
@ -74,7 +74,7 @@ pub enum HError {
|
||||||
#[fail(display = "Strip Prefix Error: {}", error)]
|
#[fail(display = "Strip Prefix Error: {}", error)]
|
||||||
StripPrefixError{#[cause] error: std::path::StripPrefixError},
|
StripPrefixError{#[cause] error: std::path::StripPrefixError},
|
||||||
#[fail(display = "INofify failed: {}", _0)]
|
#[fail(display = "INofify failed: {}", _0)]
|
||||||
INotifyError(String),
|
INotifyError(String, Backtrace),
|
||||||
#[fail(display = "Tags not loaded yet")]
|
#[fail(display = "Tags not loaded yet")]
|
||||||
TagsNotLoadedYetError,
|
TagsNotLoadedYetError,
|
||||||
#[fail(display = "Input cancelled!")]
|
#[fail(display = "Input cancelled!")]
|
||||||
|
@ -159,22 +159,6 @@ impl HError {
|
||||||
Err(HError::ConfigLineError(line))
|
Err(HError::ConfigLineError(line))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn async_not_ready<T>() -> HResult<T> {
|
|
||||||
Err(HError::AsyncNotReadyError)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn async_taken<T>() -> HResult<T> {
|
|
||||||
Err(HError::AsyncAlreadyTakenError)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn async_error<T>(error: &HError) -> HResult<T> {
|
|
||||||
Err(HError::AsyncError(format!("{}", error)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn async_started<T>() -> HResult<T> {
|
|
||||||
Err(HError::AsyncAlreadyStartedError)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn metadata_processed<T>() -> HResult<T> {
|
pub fn metadata_processed<T>() -> HResult<T> {
|
||||||
Err(HError::MetadataProcessedError)
|
Err(HError::MetadataProcessedError)
|
||||||
}
|
}
|
||||||
|
@ -246,14 +230,16 @@ impl<T> ErrorLog for Result<T, AError> {
|
||||||
|
|
||||||
impl From<std::io::Error> for HError {
|
impl From<std::io::Error> for HError {
|
||||||
fn from(error: std::io::Error) -> Self {
|
fn from(error: std::io::Error) -> Self {
|
||||||
let err = HError::IoError(format!("{}", error));
|
let err = HError::IoError(format!("{}", error),
|
||||||
|
Backtrace::new_arced());
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<failure::Error> for HError {
|
impl From<failure::Error> for HError {
|
||||||
fn from(error: failure::Error) -> Self {
|
fn from(error: failure::Error) -> Self {
|
||||||
let err = HError::Error(format!("{}", error));
|
let err = HError::Error(format!("{}", error),
|
||||||
|
Backtrace::new_arced());
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +281,7 @@ impl<T> From<std::sync::TryLockError<T>> for HError {
|
||||||
|
|
||||||
impl From<std::option::NoneError> for HError {
|
impl From<std::option::NoneError> for HError {
|
||||||
fn from(_error: std::option::NoneError) -> Self {
|
fn from(_error: std::option::NoneError) -> Self {
|
||||||
let err = HError::NoneError;
|
let err = HError::NoneError(Backtrace::new_arced());
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,14 +295,16 @@ impl From<std::path::StripPrefixError> for HError {
|
||||||
|
|
||||||
impl From<notify::Error> for HError {
|
impl From<notify::Error> for HError {
|
||||||
fn from(error: notify::Error) -> Self {
|
fn from(error: notify::Error) -> Self {
|
||||||
let err = HError::INotifyError(format!("{}", error));
|
let err = HError::INotifyError(format!("{}", error),
|
||||||
|
Backtrace::new_arced());
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<async_value::AError> for HError {
|
impl From<async_value::AError> for HError {
|
||||||
fn from(error: async_value::AError) -> Self {
|
fn from(error: async_value::AError) -> Self {
|
||||||
let err = HError::AError(error);
|
let err = HError::AError(error,
|
||||||
|
Backtrace::new_arced());
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -718,10 +718,12 @@ impl FileBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache_files(&mut self) -> HResult<()> {
|
pub fn cache_files(&mut self) -> HResult<()> {
|
||||||
let files = self.get_files()?;
|
if self.main_widget().is_ok() {
|
||||||
let selected_file = self.selected_file().ok();
|
let files = self.get_files()?;
|
||||||
self.fs_cache.put_files(files, selected_file).log();
|
let selected_file = self.selected_file().ok();
|
||||||
self.main_widget_mut()?.content.meta_updated = false;
|
self.fs_cache.put_files(files, selected_file).log();
|
||||||
|
self.main_widget_mut()?.content.meta_updated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// if self.cwd.parent().is_some() {
|
// if self.cwd.parent().is_some() {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::files::{Files, File, SortBy};
|
use crate::files::{Files, File, SortBy};
|
||||||
use crate::widget::Events;
|
use crate::widget::Events;
|
||||||
use crate::fail::{HResult, HError, ErrorLog};
|
use crate::fail::{HResult, HError, ErrorLog, Backtrace, ArcBacktrace};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -113,12 +113,12 @@ impl FsCache {
|
||||||
if self.files.read()?.contains_key(dir) {
|
if self.files.read()?.contains_key(dir) {
|
||||||
self.get_cached_files(dir)
|
self.get_cached_files(dir)
|
||||||
} else {
|
} else {
|
||||||
self.add_watch(&dir).log();
|
|
||||||
let dir = dir.clone();
|
let dir = dir.clone();
|
||||||
let selection = self.get_selection(&dir).ok();
|
let selection = self.get_selection(&dir).ok();
|
||||||
let cache = self.clone();
|
let cache = self.clone();
|
||||||
let files = Async::new(move |_| {
|
let files = Async::new(move |_| {
|
||||||
let mut files = Files::new_from_path_cancellable(&dir.path, stale)?;
|
let mut files = Files::new_from_path_cancellable(&dir.path, stale)?;
|
||||||
|
cache.add_watch(&dir).log();
|
||||||
FsCache::apply_settingss(&cache, &mut files).ok();
|
FsCache::apply_settingss(&cache, &mut files).ok();
|
||||||
Ok(files)
|
Ok(files)
|
||||||
});
|
});
|
||||||
|
@ -127,11 +127,11 @@ impl FsCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_files_sync(&self, dir: &File) -> HResult<Files> {
|
pub fn get_files_sync(&self, dir: &File) -> HResult<Files> {
|
||||||
self.add_watch(&dir).log();
|
|
||||||
let files = self.get_files(&dir, Stale::new())?.1;
|
let files = self.get_files(&dir, Stale::new())?.1;
|
||||||
let mut files = files.run_sync()?;
|
let mut files = files.run_sync()?;
|
||||||
FsCache::apply_settingss(&self, &mut files).ok();
|
FsCache::apply_settingss(&self, &mut files).ok();
|
||||||
let files = FsCache::ensure_not_empty(files)?;
|
let files = FsCache::ensure_not_empty(files)?;
|
||||||
|
self.add_watch(&dir).log();
|
||||||
Ok(files)
|
Ok(files)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,8 +188,8 @@ impl FsCache {
|
||||||
|
|
||||||
fn add_watch(&self, dir: &File) -> HResult<()> {
|
fn add_watch(&self, dir: &File) -> HResult<()> {
|
||||||
if !self.watched_dirs.read()?.contains(&dir) {
|
if !self.watched_dirs.read()?.contains(&dir) {
|
||||||
|
self.watcher.write()?.watch(&dir.path, RecursiveMode::NonRecursive)?;
|
||||||
self.watched_dirs.write()?.insert(dir.clone());
|
self.watched_dirs.write()?.insert(dir.clone());
|
||||||
self.watcher.write()?.watch(&dir.path, RecursiveMode::NonRecursive)?
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ impl FsCache {
|
||||||
let mut files = file_cache.read()
|
let mut files = file_cache.read()
|
||||||
.map_err(|e| HError::from(e))?
|
.map_err(|e| HError::from(e))?
|
||||||
.get(&dir)
|
.get(&dir)
|
||||||
.ok_or(HError::NoneError)?
|
.ok_or(HError::NoneError(Backtrace::new_arced()))?
|
||||||
.clone();
|
.clone();
|
||||||
let tab_settings = &tab_settings;
|
let tab_settings = &tab_settings;
|
||||||
|
|
||||||
|
@ -373,9 +373,11 @@ impl PathFromEvent for DebouncedEvent {
|
||||||
DebouncedEvent::NoticeRemove(path) => Ok(path),
|
DebouncedEvent::NoticeRemove(path) => Ok(path),
|
||||||
DebouncedEvent::Rename(old_path, _) => Ok(old_path),
|
DebouncedEvent::Rename(old_path, _) => Ok(old_path),
|
||||||
DebouncedEvent::Error(err, path)
|
DebouncedEvent::Error(err, path)
|
||||||
=> Err(HError::INotifyError(format!("{}, {:?}", err, path))),
|
=> Err(HError::INotifyError(format!("{}, {:?}", err, path),
|
||||||
|
Backtrace::new_arced())),
|
||||||
DebouncedEvent::Rescan
|
DebouncedEvent::Rescan
|
||||||
=> Err(HError::INotifyError("Need to rescan".to_string()))
|
=> Err(HError::INotifyError("Need to rescan".to_string(),
|
||||||
|
Backtrace::new_arced()))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,9 +548,11 @@ impl Widget for ProcView {
|
||||||
fn refresh(&mut self) -> HResult<()> {
|
fn refresh(&mut self) -> HResult<()> {
|
||||||
self.hbox.refresh().log();
|
self.hbox.refresh().log();
|
||||||
|
|
||||||
self.show_output().log();
|
if self.get_listview().len() > 0 {
|
||||||
self.get_listview_mut().refresh().log();
|
self.show_output().log();
|
||||||
self.get_textview().refresh().log();
|
self.get_listview_mut().refresh().log();
|
||||||
|
self.get_textview().refresh().log();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue