superzanti / ServerSync

Sync files between client and server for Minecraft Forge
GNU General Public License v3.0
163 stars 26 forks source link

Warn instead of crash on scanning directories with insufficient privileges #299

Closed ScrelliCopter closed 11 months ago

ScrelliCopter commented 2 years ago

Serversync Version:

v4.2.0

Minecraft Version:

Not particularly relevant but 1.19 w/ Fabric

Issue:

We run ServerSync in the same directory as our Minecraft server and ServerSync is running under a separate user to the main Minecraft process. It appears on version upgrades WorldEdit will create a transitory directory under config/worldedit/.archive-unpack/<some unique 8 char alphanum> with the unfortunate permissions of drwx------. ServerSync's file scan appears to recurse into folders that aren't included or are ignored, which is fair enough. But if it runs into directories that the user has insufficient privileges to access it will throw a java.nio.file.AccessDeniedException shortly after logging [ServerSync] INFO: Server configured to push client only mods, clients can still refuse these mods! and die. Since it's seemingly not possible to completely exclude a path from scanning the only fix is to manually fix the permissions or delete the offending directory. I think a better behaviour would be to log a warning about inaccessible directories, or perhaps only fail with a fatal error for dirs that fall under included/non-ignored rules.

Full exception:

java.io.UncheckedIOException: java.nio.file.AccessDeniedException: <snip>/config/worldedit/.archive-unpack/2e1dd752
        at java.base/java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:87)
        at java.base/java.nio.file.FileTreeIterator.hasNext(FileTreeIterator.java:103)
        at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
        at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
        at com.superzanti.serversync.server.ServerSetup.populateManifest(ServerSetup.java:64)
        at com.superzanti.serversync.server.ServerSetup.<init>(ServerSetup.java:117)
        at com.superzanti.serversync.ServerSync.runInServerMode(ServerSync.java:117)
        at com.superzanti.serversync.ServerSync.call(ServerSync.java:71)
        at com.superzanti.serversync.ServerSync.call(ServerSync.java:25)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1853)
        at picocli.CommandLine.access$1100(CommandLine.java:145)
        at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2255)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2249)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2213)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2080)
        at picocli.CommandLine.execute(CommandLine.java:1978)
        at com.superzanti.serversync.ServerSync.main(ServerSync.java:61)
Caused by: java.nio.file.AccessDeniedException: <snip>/config/worldedit/.archive-unpack/2e1dd752
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:440)
        at java.base/java.nio.file.Files.newDirectoryStream(Files.java:482)
        at java.base/java.nio.file.FileTreeWalker.visit(FileTreeWalker.java:301)
        at java.base/java.nio.file.FileTreeWalker.next(FileTreeWalker.java:374)
        at java.base/java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:83)
        ... 21 more
rheimus commented 11 months ago

Sadly there does not appear to be a nice way to use Files.walk() streams while ignoring errors.

Switched to walkFileTree, this does not benefit from parallel stream things, will have to look into it more another time.

rheimus commented 11 months ago

Closing, feel free to reopen if its still an issue