mirror of
https://github.com/sharkdp/fd.git
synced 2024-11-18 01:40:34 +01:00
Proper error handling within walk.rs
This commit is contained in:
parent
bce95274e3
commit
4590ae8535
5 changed files with 38 additions and 48 deletions
11
src/error.rs
11
src/error.rs
|
@ -1,10 +1,3 @@
|
|||
macro_rules! print_error {
|
||||
($($arg:tt)*) => (eprintln!("[fd error]: {}", format!($($arg)*)))
|
||||
}
|
||||
|
||||
macro_rules! print_error_and_exit {
|
||||
($($arg:tt)*) => {
|
||||
print_error!($($arg)*);
|
||||
::std::process::exit(1);
|
||||
};
|
||||
pub fn print_error(msg: impl Into<String>) {
|
||||
eprintln!("[fd error]: {}", msg.into());
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::io::Write;
|
|||
use std::process::Command;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::error::print_error;
|
||||
use crate::exit_codes::ExitCode;
|
||||
|
||||
/// Executes a command.
|
||||
|
@ -30,11 +31,11 @@ pub fn execute_command(mut cmd: Command, out_perm: &Mutex<()>) -> ExitCode {
|
|||
}
|
||||
}
|
||||
Err(ref why) if why.kind() == io::ErrorKind::NotFound => {
|
||||
print_error!("Command not found: {:?}", cmd);
|
||||
print_error(format!("Command not found: {:?}", cmd));
|
||||
ExitCode::GeneralError
|
||||
}
|
||||
Err(why) => {
|
||||
print_error!("Problem while executing command: {}", why);
|
||||
print_error(format!("Problem while executing command: {}", why));
|
||||
ExitCode::GeneralError
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
use super::CommandTemplate;
|
||||
use crate::exit_codes::{merge_exitcodes, ExitCode};
|
||||
use crate::walk::WorkerResult;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::Receiver;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::error::print_error;
|
||||
use crate::exit_codes::{merge_exitcodes, ExitCode};
|
||||
use crate::walk::WorkerResult;
|
||||
|
||||
use super::CommandTemplate;
|
||||
|
||||
/// An event loop that listens for inputs from the `rx` receiver. Each received input will
|
||||
/// generate a command with the supplied command template. The generated command will then
|
||||
/// be executed, and this process will continue until the receiver's sender has closed.
|
||||
|
@ -25,7 +28,7 @@ pub fn job(
|
|||
Ok(WorkerResult::Entry(val)) => val,
|
||||
Ok(WorkerResult::Error(err)) => {
|
||||
if show_filesystem_errors {
|
||||
print_error!("{}", err);
|
||||
print_error(err.to_string());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -50,7 +53,7 @@ pub fn batch(
|
|||
WorkerResult::Entry(val) => Some(val),
|
||||
WorkerResult::Error(err) => {
|
||||
if show_filesystem_errors {
|
||||
print_error!("{}", err);
|
||||
print_error(err.to_string());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -303,9 +303,7 @@ fn run() -> Result<ExitCode> {
|
|||
)
|
||||
})?;
|
||||
|
||||
let exit_code = walk::scan(&dir_vec, Arc::new(re), Arc::new(config));
|
||||
|
||||
Ok(exit_code)
|
||||
walk::scan(&dir_vec, Arc::new(re), Arc::new(config))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
53
src/walk.rs
53
src/walk.rs
|
@ -1,9 +1,3 @@
|
|||
use crate::exec;
|
||||
use crate::exit_codes::{merge_exitcodes, ExitCode};
|
||||
use crate::filesystem;
|
||||
use crate::options::Options;
|
||||
use crate::output;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::{FileType, Metadata};
|
||||
|
@ -16,10 +10,18 @@ use std::sync::{Arc, Mutex};
|
|||
use std::thread;
|
||||
use std::time;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use ignore::overrides::OverrideBuilder;
|
||||
use ignore::{self, WalkBuilder};
|
||||
use regex::bytes::Regex;
|
||||
|
||||
use crate::error::print_error;
|
||||
use crate::exec;
|
||||
use crate::exit_codes::{merge_exitcodes, ExitCode};
|
||||
use crate::filesystem;
|
||||
use crate::options::Options;
|
||||
use crate::output;
|
||||
|
||||
/// The receiver thread can either be buffering results or directly streaming to the console.
|
||||
enum ReceiverMode {
|
||||
/// Receiver is still buffering in order to sort the results, if the search finishes fast
|
||||
|
@ -44,7 +46,7 @@ pub const MAX_BUFFER_LENGTH: usize = 1000;
|
|||
/// If the `--exec` argument was supplied, this will create a thread pool for executing
|
||||
/// jobs in parallel from a given command line and the discovered paths. Otherwise, each
|
||||
/// path will simply be written to standard output.
|
||||
pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<Options>) -> ExitCode {
|
||||
pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<Options>) -> Result<ExitCode> {
|
||||
let mut path_iter = path_vec.iter();
|
||||
let first_path_buf = path_iter
|
||||
.next()
|
||||
|
@ -54,14 +56,13 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<Options>) ->
|
|||
let mut override_builder = OverrideBuilder::new(first_path_buf.as_path());
|
||||
|
||||
for pattern in &config.exclude_patterns {
|
||||
let res = override_builder.add(pattern);
|
||||
if res.is_err() {
|
||||
print_error_and_exit!("Malformed exclude pattern '{}'", pattern);
|
||||
}
|
||||
override_builder
|
||||
.add(pattern)
|
||||
.map_err(|e| anyhow!("Malformed exclude pattern: {}", e))?;
|
||||
}
|
||||
let overrides = override_builder.build().unwrap_or_else(|_| {
|
||||
print_error_and_exit!("Mismatch in exclude patterns");
|
||||
});
|
||||
let overrides = override_builder
|
||||
.build()
|
||||
.map_err(|_| anyhow!("Mismatch in exclude patterns"))?;
|
||||
|
||||
let mut walker = WalkBuilder::new(first_path_buf.as_path());
|
||||
walker
|
||||
|
@ -86,13 +87,10 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<Options>) ->
|
|||
match result {
|
||||
Some(ignore::Error::Partial(_)) => (),
|
||||
Some(err) => {
|
||||
print_error!(
|
||||
"{}",
|
||||
format!(
|
||||
"Malformed pattern in custom ignore file. {}.",
|
||||
err.to_string()
|
||||
)
|
||||
);
|
||||
print_error(format!(
|
||||
"Malformed pattern in custom ignore file. {}.",
|
||||
err.to_string()
|
||||
));
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
|
@ -131,7 +129,7 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<Options>) ->
|
|||
process::exit(ExitCode::KilledBySigint.into());
|
||||
}
|
||||
|
||||
exit_code
|
||||
Ok(exit_code)
|
||||
}
|
||||
|
||||
fn spawn_receiver(
|
||||
|
@ -231,7 +229,7 @@ fn spawn_receiver(
|
|||
}
|
||||
WorkerResult::Error(err) => {
|
||||
if show_filesystem_errors {
|
||||
print_error!("{}", err);
|
||||
print_error(err.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,12 +342,9 @@ fn spawn_senders(
|
|||
let entry_path = entry.path();
|
||||
|
||||
let search_str: Cow<OsStr> = if config.search_full_path {
|
||||
match filesystem::path_absolute_form(entry_path) {
|
||||
Ok(path_abs_buf) => Cow::Owned(path_abs_buf.as_os_str().to_os_string()),
|
||||
Err(_) => {
|
||||
print_error_and_exit!("Unable to retrieve absolute path.");
|
||||
}
|
||||
}
|
||||
let path_abs_buf = filesystem::path_absolute_form(entry_path)
|
||||
.expect("Retrieving absolute path succeeds");
|
||||
Cow::Owned(path_abs_buf.as_os_str().to_os_string())
|
||||
} else {
|
||||
match entry_path.file_name() {
|
||||
Some(filename) => Cow::Borrowed(filename),
|
||||
|
|
Loading…
Reference in a new issue