Skip to content

Commit

Permalink
better error on OS watcher limit, #207
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Nov 11, 2022
1 parent 94ef903 commit a9dcd2e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
25 changes: 19 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ extern crate notify;
extern crate pyo3;

use std::collections::HashSet;
use std::io::ErrorKind as IOErrorKind;
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::thread::sleep;
use std::time::{Duration, SystemTime};

use pyo3::create_exception;
use pyo3::exceptions::{PyFileNotFoundError, PyRuntimeError, PyTypeError};
use pyo3::exceptions::{PyFileNotFoundError, PyOSError, PyPermissionError, PyRuntimeError, PyTypeError};
use pyo3::prelude::*;

use notify::event::{Event, EventKind, ModifyKind, RenameMode};
use notify::{
Config as NotifyConfig, ErrorKind, PollWatcher, RecommendedWatcher, RecursiveMode, Result as NotifyResult, Watcher,
Config as NotifyConfig, ErrorKind as NotifyErrorKind, ErrorKind, PollWatcher, RecommendedWatcher, RecursiveMode,
Result as NotifyResult, Watcher,
};

create_exception!(
Expand Down Expand Up @@ -43,6 +45,19 @@ struct RustNotify {
watcher: WatcherEnum,
}

fn map_watch_error(error: notify::Error) -> PyErr {
let err_string = error.to_string();
match error.kind {
NotifyErrorKind::PathNotFound => PyFileNotFoundError::new_err(err_string),
NotifyErrorKind::Io(io_error) => match io_error.kind() {
IOErrorKind::NotFound => PyFileNotFoundError::new_err(err_string),
IOErrorKind::PermissionDenied => PyPermissionError::new_err(err_string),
_ => PyOSError::new_err(err_string),
},
_ => PyOSError::new_err(err_string),
}
}

// macro to avoid duplicated code below
macro_rules! watcher_paths {
($watcher:ident, $paths:ident, $debug:ident, $recursive:ident) => {
Expand All @@ -52,9 +67,7 @@ macro_rules! watcher_paths {
RecursiveMode::NonRecursive
};
for watch_path in $paths.into_iter() {
$watcher
.watch(Path::new(&watch_path), mode)
.map_err(|e| PyFileNotFoundError::new_err(format!("{}", e)))?;
$watcher.watch(Path::new(&watch_path), mode).map_err(map_watch_error)?;
}
if $debug {
eprintln!("watcher: {:?}", $watcher);
Expand Down Expand Up @@ -167,7 +180,7 @@ impl RustNotify {
}
Err(error) => {
match &error.kind {
ErrorKind::Io(io_error) => {
NotifyErrorKind::Io(io_error) => {
if io_error.raw_os_error() == Some(38) {
// see https://github.com/samuelcolvin/watchfiles/issues/167
// we callback to PollWatcher
Expand Down
2 changes: 1 addition & 1 deletion tests/test_rust_notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def test_move_internal(test_dir: Path):

def test_does_not_exist(tmp_path: Path):
p = tmp_path / 'missing'
with pytest.raises(FileNotFoundError):
with pytest.raises(FileNotFoundError, match='No such file or directory'):
RustNotify([str(p)], False, False, 0, True)


Expand Down

0 comments on commit a9dcd2e

Please sign in to comment.