Skip to content

Commit 9202f07

Browse files
committed
Improve error checks when we start a watch
1 parent e4e29a0 commit 9202f07

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

src/main/java/engineering/swat/watch/Watch.java

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@
2626
*/
2727
package engineering.swat.watch;
2828

29+
import java.io.FileNotFoundException;
2930
import java.io.IOException;
31+
import java.nio.file.FileSystemException;
3032
import java.nio.file.Files;
33+
import java.nio.file.InvalidPathException;
3134
import java.nio.file.LinkOption;
35+
import java.nio.file.NoSuchFileException;
36+
import java.nio.file.NotDirectoryException;
3237
import java.nio.file.Path;
3338
import java.util.concurrent.Executor;
3439
import java.util.function.BiConsumer;
@@ -76,28 +81,13 @@ private Watch(Path path, WatchScope scope) {
7681
* Watch a path for updates, optionally also get events for its children/descendants
7782
* @param path which absolute path to monitor, can be a file or a directory, but has to be absolute
7883
* @param scope for directories you can also choose to monitor it's direct children or all it's descendants
79-
* @throws IllegalArgumentException in case a path is not supported (in relation to the scope)
84+
* @throws IllegalArgumentException in case a path is not supported
8085
* @return watch builder that can be further configured and then started
8186
*/
8287
public static Watch build(Path path, WatchScope scope) {
8388
if (!path.isAbsolute()) {
8489
throw new IllegalArgumentException("We can only watch absolute paths");
8590
}
86-
switch (scope) {
87-
case PATH_AND_CHILDREN: // intended fallthrough
88-
case PATH_AND_ALL_DESCENDANTS:
89-
if (!Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
90-
throw new IllegalArgumentException("Only directories are supported for this scope: " + scope);
91-
}
92-
break;
93-
case PATH_ONLY:
94-
if (Files.isSymbolicLink(path)) {
95-
throw new IllegalArgumentException("Symlinks are not supported");
96-
}
97-
break;
98-
default:
99-
throw new IllegalArgumentException("Unsupported scope: " + scope);
100-
}
10191
return new Watch(path, scope);
10292
}
10393

@@ -192,16 +182,38 @@ public Watch onOverflow(Approximation whichFiles) {
192182
return this;
193183
}
194184

185+
private void validateOptions() throws IOException {
186+
if (this.eventHandler == EMPTY_HANDLER) {
187+
throw new IllegalStateException("There is no onEvent handler defined");
188+
}
189+
if (!Files.exists(path)) {
190+
throw new FileSystemException(path.toString(), null, "Cannot open a watch on a non-existing path");
191+
}
192+
switch (scope) {
193+
case PATH_AND_CHILDREN: // intended fallthrough
194+
case PATH_AND_ALL_DESCENDANTS:
195+
if (!Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
196+
throw new FileSystemException(path.toString(), null, "Only directories are supported for this scope: " + scope);
197+
}
198+
break;
199+
case PATH_ONLY:
200+
if (Files.isSymbolicLink(path)) {
201+
throw new FileSystemException(path.toString(), null, "Symlinks are not supported");
202+
}
203+
break;
204+
default:
205+
throw new IllegalArgumentException("Unsupported scope: " + scope);
206+
}
207+
}
208+
195209
/**
196210
* Start watch the path for events.
197211
* @return a subscription for the watch, when closed, new events will stop being registered to the worker pool.
198-
* @throws IOException in case the starting of the watcher caused an underlying IO exception
212+
* @throws IOException in case the starting of the watcher caused an underlying IO exception or we detect it is an invalid watch
199213
* @throws IllegalStateException the watchers is not configured correctly (for example, missing {@link #on(Consumer)}, or a watcher is started twice)
200214
*/
201215
public ActiveWatch start() throws IOException {
202-
if (this.eventHandler == EMPTY_HANDLER) {
203-
throw new IllegalStateException("There is no onEvent handler defined");
204-
}
216+
validateOptions();
205217
var executor = this.executor;
206218
if (executor == null) {
207219
executor = FALLBACK_EXECUTOR;

0 commit comments

Comments
 (0)