logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use std::path::PathBuf;

use miette::Diagnostic;
use thiserror::Error;
use tokio::sync::watch;

use crate::{action, fs};

/// Errors occurring from reconfigs.
#[derive(Debug, Diagnostic, Error)]
#[non_exhaustive]
#[diagnostic(url(docsrs))]
pub enum ReconfigError {
	/// Error received when the action processor cannot be updated.
	#[error("reconfig: action watch: {0}")]
	#[diagnostic(code(watchexec::reconfig::action_watch))]
	ActionWatch(#[from] watch::error::SendError<action::WorkingData>),

	/// Error received when the fs event source cannot be updated.
	#[error("reconfig: fs watch: {0}")]
	#[diagnostic(code(watchexec::reconfig::fs_watch))]
	FsWatch(#[from] watch::error::SendError<fs::WorkingData>),
}

/// Error when parsing a signal from string.
#[derive(Debug, Diagnostic, Error)]
#[error("invalid signal `{src}`: {err}")]
#[diagnostic(code(watchexec::signal::process::parse), url(docsrs))]
pub struct SignalParseError {
	// The string that was parsed.
	#[source_code]
	src: String,

	// The error that occurred.
	err: String,

	// The span of the source which is in error.
	#[label = "invalid signal"]
	span: (usize, usize),
}

impl SignalParseError {
	pub(crate) fn new(src: &str, err: &str) -> Self {
		Self {
			src: src.to_owned(),
			err: err.to_owned(),
			span: (0, src.len()),
		}
	}
}

/// Errors emitted by the filesystem watcher.
#[derive(Debug, Diagnostic, Error)]
#[non_exhaustive]
#[diagnostic(url(docsrs))]
pub enum FsWatcherError {
	/// Error received when creating a filesystem watcher fails.
	///
	/// Also see `TooManyWatches` and `TooManyHandles`.
	#[error("failed to instantiate")]
	#[diagnostic(
		code(watchexec::fs_watcher::create),
		help("perhaps retry with the poll watcher")
	)]
	Create(#[source] notify::Error),

	/// Error received when creating or updating a filesystem watcher fails because there are too many watches.
	///
	/// This is the OS error 28 on Linux.
	#[error("failed to instantiate: too many watches")]
	#[diagnostic(code(watchexec::fs_watcher::too_many_watches))]
	#[cfg_attr(target_os = "linux", diagnostic(help("you will want to increase your inotify.max_user_watches, see inotify(7) and https://watchexec.github.io/docs/inotify-limits.html")))]
	#[cfg_attr(
		not(target_os = "linux"),
		diagnostic(help("this should not happen on your platform"))
	)]
	TooManyWatches(#[source] notify::Error),

	/// Error received when creating or updating a filesystem watcher fails because there are too many file handles open.
	///
	/// This is the OS error 24 on Linux. It may also occur when the limit for inotify instances is reached.
	#[error("failed to instantiate: too many handles")]
	#[diagnostic(code(watchexec::fs_watcher::too_many_handles))]
	#[cfg_attr(target_os = "linux", diagnostic(help("you will want to increase your `nofile` limit, see pam_limits(8); or increase your inotify.max_user_instances, see inotify(7) and https://watchexec.github.io/docs/inotify-limits.html")))]
	#[cfg_attr(
		not(target_os = "linux"),
		diagnostic(help("this should not happen on your platform"))
	)]
	TooManyHandles(#[source] notify::Error),

	/// Error received when reading a filesystem event fails.
	#[error("received an event that we could not read")]
	#[diagnostic(code(watchexec::fs_watcher::event))]
	Event(#[source] notify::Error),

	/// Error received when adding to the pathset for the filesystem watcher fails.
	#[error("while adding {path:?}")]
	#[diagnostic(code(watchexec::fs_watcher::path_add))]
	PathAdd {
		/// The path that was attempted to be added.
		path: PathBuf,

		/// The underlying error.
		#[source]
		err: notify::Error,
	},

	/// Error received when removing from the pathset for the filesystem watcher fails.
	#[error("while removing {path:?}")]
	#[diagnostic(code(watchexec::fs_watcher::path_remove))]
	PathRemove {
		/// The path that was attempted to be removed.
		path: PathBuf,

		/// The underlying error.
		#[source]
		err: notify::Error,
	},
}