From bc0fe6be70352814cd937406f3f7bbb24155aaeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Sun, 16 Jan 2022 19:46:52 +1300 Subject: [PATCH] Add context to io errors --- lib/src/error.rs | 6 ------ lib/src/error/critical.rs | 17 +---------------- lib/src/error/runtime.rs | 17 ----------------- lib/src/error/specialised.rs | 17 ----------------- lib/src/filter/tagged.rs | 18 +++++++++++++++--- lib/src/filter/tagged/files.rs | 8 +++++++- lib/src/fs.rs | 5 ++++- lib/src/ignore/files.rs | 2 ++ 8 files changed, 29 insertions(+), 61 deletions(-) diff --git a/lib/src/error.rs b/lib/src/error.rs index 611a853..179a119 100644 --- a/lib/src/error.rs +++ b/lib/src/error.rs @@ -10,9 +10,3 @@ pub use specialised::*; mod critical; mod runtime; mod specialised; - -/// Helper trait to construct specific IO errors from generic ones. -pub trait SpecificIoError { - /// Add some context to the error or result. - fn about(self, context: &'static str) -> Output; -} diff --git a/lib/src/error/critical.rs b/lib/src/error/critical.rs index 8ce356e..85227b9 100644 --- a/lib/src/error/critical.rs +++ b/lib/src/error/critical.rs @@ -4,7 +4,7 @@ use tokio::{sync::mpsc, task::JoinError}; use crate::event::Event; -use super::{RuntimeError, SpecificIoError}; +use super::RuntimeError; /// Errors which are not recoverable and stop watchexec execution. #[derive(Debug, Diagnostic, Error)] @@ -63,18 +63,3 @@ pub enum CriticalError { #[diagnostic(code(watchexec::critical::internal::missing_handler))] MissingHandler, } - -impl SpecificIoError> for Result { - fn about(self, context: &'static str) -> Result { - self.map_err(|err| err.about(context)) - } -} - -impl SpecificIoError for std::io::Error { - fn about(self, context: &'static str) -> CriticalError { - CriticalError::IoError { - about: context, - err: self, - } - } -} diff --git a/lib/src/error/runtime.rs b/lib/src/error/runtime.rs index 1dfbadb..eb61e39 100644 --- a/lib/src/error/runtime.rs +++ b/lib/src/error/runtime.rs @@ -6,8 +6,6 @@ use tokio::sync::mpsc; use crate::{event::Event, fs::Watcher, signal::process::SubSignal}; -use super::SpecificIoError; - /// Errors which _may_ be recoverable, transient, or only affect a part of the operation, and should /// be reported to the user and/or acted upon programatically, but will not outright stop watchexec. #[derive(Debug, Diagnostic, Error)] @@ -227,18 +225,3 @@ pub enum RuntimeError { #[diagnostic(code(watchexec::runtime::set))] Set(#[related] Vec), } - -impl SpecificIoError> for Result { - fn about(self, context: &'static str) -> Result { - self.map_err(|err| err.about(context)) - } -} - -impl SpecificIoError for std::io::Error { - fn about(self, context: &'static str) -> RuntimeError { - RuntimeError::IoError { - about: context, - err: self, - } - } -} diff --git a/lib/src/error/specialised.rs b/lib/src/error/specialised.rs index dc17ede..ea1070f 100644 --- a/lib/src/error/specialised.rs +++ b/lib/src/error/specialised.rs @@ -13,8 +13,6 @@ use crate::{ ignore::IgnoreFilterer, }; -use super::SpecificIoError; - /// Errors occurring from reconfigs. #[derive(Debug, Diagnostic, Error)] #[non_exhaustive] @@ -160,18 +158,3 @@ impl From for RuntimeError { } } } - -impl SpecificIoError> for Result { - fn about(self, context: &'static str) -> Result { - self.map_err(|err| err.about(context)) - } -} - -impl SpecificIoError for std::io::Error { - fn about(self, context: &'static str) -> TaggedFiltererError { - TaggedFiltererError::IoError { - about: context, - err: self, - } - } -} diff --git a/lib/src/filter/tagged.rs b/lib/src/filter/tagged.rs index bbf030c..63e235f 100644 --- a/lib/src/filter/tagged.rs +++ b/lib/src/filter/tagged.rs @@ -328,13 +328,19 @@ impl TaggedFilterer { origin: impl Into, workdir: impl Into, ) -> Result, TaggedFiltererError> { - let origin = canonicalize(origin.into())?; + let origin = canonicalize(origin.into()).map_err(|err| TaggedFiltererError::IoError { + about: "canonicalise origin on new tagged filterer", + err, + })?; Ok(Arc::new(Self { filters: swaplock::SwapLock::new(HashMap::new()), ignore_filterer: swaplock::SwapLock::new(IgnoreFilterer::empty(&origin)), glob_compiled: swaplock::SwapLock::new(None), not_glob_compiled: swaplock::SwapLock::new(None), - workdir: canonicalize(workdir.into())?, + workdir: canonicalize(workdir.into()).map_err(|err| TaggedFiltererError::IoError { + about: "canonicalise workdir on new tagged filterer", + err, + })?, origin, })) } @@ -662,7 +668,13 @@ impl Filter { /// Returns the filter with its `in_path` canonicalised. pub fn canonicalised(mut self) -> Result { if let Some(ctx) = self.in_path { - self.in_path = Some(canonicalize(&ctx)?); + self.in_path = + Some( + canonicalize(&ctx).map_err(|err| TaggedFiltererError::IoError { + about: "canonicalise Filter in_path", + err, + })?, + ); trace!(canon=?ctx, "canonicalised in_path"); } diff --git a/lib/src/filter/tagged/files.rs b/lib/src/filter/tagged/files.rs index 6f4d986..d49a046 100644 --- a/lib/src/filter/tagged/files.rs +++ b/lib/src/filter/tagged/files.rs @@ -74,7 +74,13 @@ impl FilterFile { /// /// This method reads the entire file into memory. pub async fn load(&self) -> Result, TaggedFiltererError> { - let content = read_to_string(&self.0.path).await?; + let content = + read_to_string(&self.0.path) + .await + .map_err(|err| TaggedFiltererError::IoError { + about: "filter file load", + err, + })?; let lines = content.lines(); let mut filters = Vec::with_capacity(lines.size_hint().0); diff --git a/lib/src/fs.rs b/lib/src/fs.rs index 9506cb7..0b4546c 100644 --- a/lib/src/fs.rs +++ b/lib/src/fs.rs @@ -286,7 +286,10 @@ fn process_event( // possibly pull file_type from whatever notify (or the native driver) returns? tags.push(Tag::Path { file_type: metadata(&path).ok().map(|m| m.file_type().into()), - path: dunce::canonicalize(path)?, + path: dunce::canonicalize(path).map_err(|err| RuntimeError::IoError { + about: "canonicalise path in event", + err, + })?, }); } diff --git a/lib/src/ignore/files.rs b/lib/src/ignore/files.rs index 0c01323..c90c35d 100644 --- a/lib/src/ignore/files.rs +++ b/lib/src/ignore/files.rs @@ -281,6 +281,8 @@ pub async fn from_environment() -> (Vec, Vec) { (files, errors) } +// TODO: add context to these errors + #[inline] pub(crate) async fn discover_file( files: &mut Vec,