Skip to content

Commit 5853075

Browse files
authored
sync: provide more info when "Failed to sync and interpolate" (#601)
1 parent 3de1186 commit 5853075

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package me.itzg.helpers.errors;
2+
3+
import java.util.ArrayList;
4+
import java.util.Iterator;
5+
6+
public class ExceptionDetailer {
7+
8+
private static class CauseIterator implements Iterator<Throwable> {
9+
private Throwable current;
10+
11+
CauseIterator(Throwable initial) {
12+
this.current = initial;
13+
}
14+
15+
@Override
16+
public boolean hasNext() {
17+
return current != null;
18+
}
19+
20+
public Throwable next() {
21+
if (current == null) {
22+
return null;
23+
}
24+
Throwable result = current;
25+
current = current.getCause();
26+
return result;
27+
}
28+
}
29+
30+
public static String buildCausalMessages(Throwable throwable) {
31+
final CauseIterator causeIterator = new CauseIterator(throwable);
32+
final ArrayList<String> parts = new ArrayList<>();
33+
while (causeIterator.hasNext()) {
34+
final Throwable cause = causeIterator.next();
35+
if (cause != null) {
36+
parts.add(cause.getClass().getSimpleName() + ": " + cause.getMessage());
37+
}
38+
}
39+
return String.join("; ", parts);
40+
}
41+
}

src/main/java/me/itzg/helpers/sync/SynchronizingFileVisitor.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import java.nio.file.attribute.FileTime;
1010
import java.util.List;
1111
import lombok.extern.slf4j.Slf4j;
12+
import me.itzg.helpers.errors.ExceptionDetailer;
13+
import me.itzg.helpers.errors.InvalidParameterException;
1214

1315
@Slf4j
1416
class SynchronizingFileVisitor implements FileVisitor<Path> {
@@ -24,9 +26,21 @@ public SynchronizingFileVisitor(Path src, Path dest, boolean skipNewerInDestinat
2426
this.fileProcessor = fileProcessor;
2527
}
2628

29+
/**
30+
* Convenience method that processes each source path into the destination path by applying a {@link SynchronizingFileVisitor}
31+
* to each source.
32+
* @param srcDest source... dest
33+
* @param skipNewerInDestination provided to {@link SynchronizingFileVisitor}
34+
* @param fileProcessor provided to {@link SynchronizingFileVisitor}
35+
* @return exit code style of 1 for failure, 0 for success
36+
*/
2737
static int walkDirectories(List<Path> srcDest, boolean skipNewerInDestination,
2838
FileProcessor fileProcessor
2939
) {
40+
if (srcDest.size() < 2) {
41+
throw new InvalidParameterException("At least one source and destination path is required");
42+
}
43+
3044
// TODO can use getLast() with java 21
3145
final Path dest = srcDest.get(srcDest.size() - 1);
3246

@@ -35,7 +49,7 @@ static int walkDirectories(List<Path> srcDest, boolean skipNewerInDestination,
3549
try {
3650
Files.walkFileTree(src, new SynchronizingFileVisitor(src, dest, skipNewerInDestination, fileProcessor));
3751
} catch (IOException e) {
38-
log.error("Failed to sync and interpolate {} into {} : {}", src, dest, e.getMessage());
52+
log.error("Failed to sync and interpolate {} into {}: {}", src, dest, ExceptionDetailer.buildCausalMessages(e));
3953
log.debug("Details", e);
4054
return 1;
4155
}
@@ -104,7 +118,7 @@ private boolean shouldProcessFile(Path srcFile, Path destFile) throws IOExceptio
104118

105119
@Override
106120
public FileVisitResult visitFileFailed(Path file, IOException e) {
107-
log.warn("Failed to visit file {} due to {}:{}", file, e.getClass(), e.getMessage());
121+
log.warn("Failed to visit file {} due to {}", file, ExceptionDetailer.buildCausalMessages(e));
108122
log.debug("Details", e);
109123
return FileVisitResult.CONTINUE;
110124
}

0 commit comments

Comments
 (0)