Pārlūkot izejas kodu

Fix crash when listing conflicts

If the file is removed between us initially scanning it and later fetching
some details, we could crash. Fix that.

Fixes #349
Antony Male 8 gadi atpakaļ
vecāks
revīzija
f16931a5f6

+ 15 - 7
src/SyncTrayzor/Services/Conflicts/ConflictFileManager.cs

@@ -159,7 +159,7 @@ namespace SyncTrayzor.Services.Conflicts
                 var searchDirectory = stack.Pop();
                 var directory = searchDirectory.Directory;
 
-                this.TryFilesystemOperation(() =>
+                this.TryFilesystemEnumeration(() =>
                 {
                     foreach (var filePath in this.filesystemProvider.EnumerateFiles(directory, conflictPattern, System.IO.SearchOption.TopDirectoryOnly))
                     {
@@ -185,15 +185,23 @@ namespace SyncTrayzor.Services.Conflicts
 
                 foreach (var kvp in conflictLookup)
                 {
-                    var file = new ConflictFile(kvp.Key, this.filesystemProvider.GetLastWriteTime(kvp.Key), this.filesystemProvider.GetFileSize(kvp.Key));
-                    var conflicts = kvp.Value.Select(x => new ConflictOption(x.FilePath, this.filesystemProvider.GetLastWriteTime(x.FilePath), x.Created, this.filesystemProvider.GetFileSize(x.FilePath))).ToList();
-                    observer.OnNext(new ConflictSet(file, conflicts));
-                    cancellationToken.ThrowIfCancellationRequested();
+                    // The file can have disappeared between us finding it, and this
+                    try
+                    {
+                        var file = new ConflictFile(kvp.Key, this.filesystemProvider.GetLastWriteTime(kvp.Key), this.filesystemProvider.GetFileSize(kvp.Key));
+                        var conflicts = kvp.Value.Select(x => new ConflictOption(x.FilePath, this.filesystemProvider.GetLastWriteTime(x.FilePath), x.Created, this.filesystemProvider.GetFileSize(x.FilePath))).ToList();
+                        observer.OnNext(new ConflictSet(file, conflicts));
+                        cancellationToken.ThrowIfCancellationRequested();
+                    }
+                    catch (Exception e)
+                    {
+                        logger.Error(e, $"Error while trying to access {kvp.Key}, maybe it was deleted since we scanned it?");
+                    }
                 }
 
                 if (searchDirectory.Depth < maxSearchDepth)
                 {
-                    this.TryFilesystemOperation(() =>
+                    this.TryFilesystemEnumeration(() =>
                     {
                         foreach (var subDirectory in this.filesystemProvider.EnumerateDirectories(directory, "*", System.IO.SearchOption.TopDirectoryOnly))
                         {
@@ -213,7 +221,7 @@ namespace SyncTrayzor.Services.Conflicts
             }
         }
 
-        private void TryFilesystemOperation(Action action, string path, string itemType)
+        private void TryFilesystemEnumeration(Action action, string path, string itemType)
         {
             try
             {