Skip to content

Commit 52e92f5

Browse files
authored
Merge pull request #70 from claucambra/bugfix/errors-building
Build .noSuchItem and .filenameCollision errors correctly
2 parents 17f8d42 + 7b801bd commit 52e92f5

11 files changed

Lines changed: 246 additions & 128 deletions

File tree

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ func item(
5252
if let item = Item.storedItem(identifier: identifier, remoteInterface: ncKit) {
5353
completionHandler(item, nil)
5454
} else {
55-
completionHandler(nil, NSFileProviderError(.noSuchItem))
55+
completionHandler(
56+
nil, NSError.fileProviderErrorForNonExistentItem(withIdentifier: identifier)
57+
)
5658
}
5759
return Progress()
5860
}
@@ -77,7 +79,9 @@ func fetchContents(
7779
}
7880

7981
guard let item = Item.storedItem(identifier: itemIdentifier, remoteInterface: ncKit) else {
80-
completionHandler(nil, nil, NSFileProviderError(.noSuchItem))
82+
completionHandler(
83+
nil, nil, NSError.fileProviderErrorForNonExistentItem(withIdentifier: itemIdentifier)
84+
)
8185
return Progress()
8286
}
8387

@@ -131,7 +135,12 @@ func modifyItem(
131135
completionHandler: @escaping (NSFileProviderItem?, NSFileProviderItemFields, Bool, Error?) -> Void
132136
) -> Progress {
133137
guard let existingItem = Item.storedItem(identifier: item.itemIdentifier, remoteInterface: ncKit) else {
134-
completionHandler(item, [], false, NSFileProviderError(.noSuchItem))
138+
completionHandler(
139+
item,
140+
[],
141+
false,
142+
NSError.fileProviderErrorForNonExistentItem(withIdentifier: item.itemIdentifier)
143+
)
135144
return Progress()
136145
}
137146

@@ -164,7 +173,7 @@ func deleteItem(
164173
completionHandler: @escaping (Error?) -> Void
165174
) -> Progress {
166175
guard let item = Item.storedItem(identifier: identifier, remoteInterface: ncKit) else {
167-
completionHandler(NSFileProviderError(.noSuchItem))
176+
completionHandler(NSError.fileProviderErrorForNonExistentItem(withIdentifier: identifier))
168177
return Progress()
169178
}
170179

Sources/NextcloudFileProviderKit/Database/FilesDatabaseManager.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ public let databaseFilename = "fileproviderextdatabase.realm"
2525

2626
public final class FilesDatabaseManager: Sendable {
2727
private static let schemaVersion = stable2_0SchemaVersion
28-
2928
static let logger = Logger(subsystem: Logger.subsystem, category: "filesdatabase")
29+
let account: Account
3030

3131
var itemMetadatas: Results<RealmItemMetadata> { ncDatabase().objects(RealmItemMetadata.self) }
3232

@@ -36,6 +36,8 @@ public final class FilesDatabaseManager: Sendable {
3636
fileProviderDataDirUrl: URL? = pathForFileProviderExtData(),
3737
relativeDatabaseFolderPath: String = relativeDatabaseFolderPath
3838
) {
39+
self.account = account
40+
3941
let fm = FileManager.default
4042
let dbPath = realmConfig.fileURL?.path
4143
let migrate = dbPath != nil && !fm.fileExists(atPath: dbPath!)

Sources/NextcloudFileProviderKit/Enumeration/Enumerator.swift

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,9 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
159159
)
160160

161161
guard trashReadError == .success else {
162-
let error =
163-
trashReadError.fileProviderError ?? NSFileProviderError(.cannotSynchronize)
162+
let error = trashReadError.fileProviderError(
163+
handlingNoSuchItemErrorUsingItemIdentifier: self.enumeratedItemIdentifier
164+
) ?? NSFileProviderError(.cannotSynchronize)
164165
listener?.enumerationActionFailed(actionId: actionId, error: error)
165166
observer.finishEnumeratingWithError(error)
166167
return
@@ -193,10 +194,11 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
193194
For identifier: \(self.enumeratedItemIdentifier.rawValue, privacy: .public)
194195
"""
195196
)
196-
listener?.enumerationActionFailed(
197-
actionId: actionId, error: NSFileProviderError(.noSuchItem)
197+
let error = NSError.fileProviderErrorForNonExistentItem(
198+
withIdentifier: self.enumeratedItemIdentifier
198199
)
199-
observer.finishEnumeratingWithError(NSFileProviderError(.noSuchItem))
200+
listener?.enumerationActionFailed(actionId: actionId, error: error)
201+
observer.finishEnumeratingWithError(error)
200202
return
201203
}
202204

@@ -229,8 +231,9 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
229231
)
230232

231233
// TODO: Refactor for conciseness
232-
let error =
233-
readError?.fileProviderError ?? NSFileProviderError(.cannotSynchronize)
234+
let error = readError?.fileProviderError(
235+
handlingNoSuchItemErrorUsingItemIdentifier: self.enumeratedItemIdentifier
236+
) ?? NSFileProviderError(.cannotSynchronize)
234237
listener?.enumerationActionFailed(actionId: actionId, error: error)
235238
observer.finishEnumeratingWithError(error)
236239
return
@@ -350,8 +353,9 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
350353
"""
351354
)
352355
// TODO: Refactor for conciseness
353-
let fpError =
354-
error?.fileProviderError ?? NSFileProviderError(.cannotSynchronize)
356+
let fpError = error?.fileProviderError(
357+
handlingNoSuchItemErrorUsingItemIdentifier: self.enumeratedItemIdentifier
358+
) ?? NSFileProviderError(.cannotSynchronize)
355359
listener?.enumerationActionFailed(actionId: actionId, error: fpError)
356360
observer.finishEnumeratingWithError(fpError)
357361
return
@@ -367,6 +371,7 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
367371
Self.completeChangesObserver(
368372
observer,
369373
anchor: anchor,
374+
enumeratedItemIdentifier: self.enumeratedItemIdentifier,
370375
account: account,
371376
remoteInterface: remoteInterface,
372377
dbManager: dbManager,
@@ -398,8 +403,9 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
398403
)
399404

400405
guard trashReadError == .success else {
401-
let error =
402-
trashReadError.fileProviderError ?? NSFileProviderError(.cannotSynchronize)
406+
let error = trashReadError.fileProviderError(
407+
handlingNoSuchItemErrorUsingItemIdentifier: self.enumeratedItemIdentifier
408+
) ?? NSFileProviderError(.cannotSynchronize)
403409
listener?.enumerationActionFailed(actionId: actionId, error: error)
404410
observer.finishEnumeratingWithError(error)
405411
return
@@ -454,7 +460,9 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
454460
"""
455461
)
456462

457-
let error = readError!.fileProviderError ?? NSFileProviderError(.cannotSynchronize)
463+
let error = readError?.fileProviderError(
464+
handlingNoSuchItemErrorUsingItemIdentifier: self.enumeratedItemIdentifier
465+
) ?? NSFileProviderError(.cannotSynchronize)
458466

459467
if readError!.isNotFoundError {
460468
Self.logger.info(
@@ -498,6 +506,7 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
498506
Self.completeChangesObserver(
499507
observer,
500508
anchor: anchor,
509+
enumeratedItemIdentifier: self.enumeratedItemIdentifier,
501510
account: account,
502511
remoteInterface: remoteInterface,
503512
dbManager: dbManager,
@@ -534,6 +543,7 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
534543
Self.completeChangesObserver(
535544
observer,
536545
anchor: anchor,
546+
enumeratedItemIdentifier: self.enumeratedItemIdentifier,
537547
account: account,
538548
remoteInterface: remoteInterface,
539549
dbManager: dbManager,
@@ -591,6 +601,7 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
591601
private static func completeChangesObserver(
592602
_ observer: NSFileProviderChangeObserver,
593603
anchor: NSFileProviderSyncAnchor,
604+
enumeratedItemIdentifier: NSFileProviderItemIdentifier,
594605
account: Account,
595606
remoteInterface: RemoteInterface,
596607
dbManager: FilesDatabaseManager,
@@ -602,10 +613,14 @@ public class Enumerator: NSObject, NSFileProviderEnumerator {
602613
Self.logger.error(
603614
"""
604615
Received invalid newMetadatas, updatedMetadatas or deletedMetadatas.
605-
Finished enumeration of changes with error.
616+
Finished enumeration of changes with error.
606617
"""
607618
)
608-
observer.finishEnumeratingWithError(NSFileProviderError(.noSuchItem))
619+
observer.finishEnumeratingWithError(
620+
NSError.fileProviderErrorForNonExistentItem(
621+
withIdentifier: enumeratedItemIdentifier
622+
)
623+
)
609624
return
610625
}
611626

Sources/NextcloudFileProviderKit/Extensions/NKError+Extensions.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,40 @@ extension NKError {
6363
NSFileProviderError(.notAuthenticated)
6464
} else if isGoingOverQuotaError {
6565
NSFileProviderError(.insufficientQuota)
66+
} else if matchesCollisionError {
67+
NSFileProviderError(.filenameCollision)
6668
} else {
6769
NSFileProviderError(.cannotSynchronize)
6870
}
6971
}
72+
73+
func fileProviderError(
74+
handlingNoSuchItemErrorUsingItemIdentifier identifier: NSFileProviderItemIdentifier
75+
) -> Error? {
76+
guard fileProviderError?.code == .noSuchItem else {
77+
return fileProviderError as Error?
78+
}
79+
return NSError.fileProviderErrorForNonExistentItem(withIdentifier: identifier)
80+
}
81+
82+
func fileProviderError(
83+
handlingCollisionAgainstItemInRemotePath problemRemotePath: String,
84+
dbManager: FilesDatabaseManager,
85+
remoteInterface: RemoteInterface
86+
) -> Error? {
87+
guard fileProviderError?.code == .filenameCollision else {
88+
return fileProviderError as Error?
89+
}
90+
guard let collidingItemMetadata = dbManager.itemMetadata(
91+
account: dbManager.account.ncKitAccount, locatedAtRemoteUrl: problemRemotePath
92+
), let collidingItem = Item.storedItem(
93+
identifier: .init(collidingItemMetadata.ocId),
94+
account: dbManager.account,
95+
remoteInterface: remoteInterface,
96+
dbManager: dbManager
97+
) else {
98+
return NSFileProviderError(.filenameCollision)
99+
}
100+
return NSError.fileProviderErrorForCollision(with: collidingItem)
101+
}
70102
}

0 commit comments

Comments
 (0)