[error-handling]: Improved Error handling for all OperationTypes in AppManager

This commit is contained in:
Magesh K
2024-12-13 16:30:24 +05:30
parent d045c0ed4d
commit 9597c7deb6
2 changed files with 80 additions and 56 deletions

View File

@@ -1407,7 +1407,9 @@ private extension AppManager
verifyPledgeOperation?.resultHandler = { result in verifyPledgeOperation?.resultHandler = { result in
switch result switch result
{ {
case .failure(let error): context.error = error case .failure(let error):
context.error = error
completionHandler(.failure(error))
case .success: break case .success: break
} }
} }
@@ -1421,10 +1423,16 @@ private extension AppManager
{ {
let app = try result.get() let app = try result.get()
context.app = app context.app = app
if cacheApp
{
try FileManager.default.copyItem(at: app.fileURL, to: InstalledApp.fileURL(for: app), shouldReplace: true)
}
} }
catch catch
{ {
context.error = error context.error = error
completionHandler(.failure(error))
} }
} }
progress.addChild(downloadOperation.progress, withPendingUnitCount: 25) progress.addChild(downloadOperation.progress, withPendingUnitCount: 25)
@@ -1508,7 +1516,9 @@ private extension AppManager
refreshAnisetteDataOperation.resultHandler = { (result) in refreshAnisetteDataOperation.resultHandler = { (result) in
switch result switch result
{ {
case .failure(let error): context.error = error case .failure(let error):
context.error = error
completionHandler(.failure(error))
case .success(let anisetteData): group.context.session?.anisetteData = anisetteData case .success(let anisetteData): group.context.session?.anisetteData = anisetteData
} }
} }
@@ -1521,7 +1531,9 @@ private extension AppManager
fetchProvisioningProfilesOperation.resultHandler = { (result) in fetchProvisioningProfilesOperation.resultHandler = { (result) in
switch result switch result
{ {
case .failure(let error): context.error = error case .failure(let error):
context.error = error
completionHandler(.failure(error))
case .success(let provisioningProfiles): case .success(let provisioningProfiles):
context.provisioningProfiles = provisioningProfiles context.provisioningProfiles = provisioningProfiles
print("PROVISIONING PROFILES \(context.provisioningProfiles)") print("PROVISIONING PROFILES \(context.provisioningProfiles)")
@@ -1659,7 +1671,9 @@ private extension AppManager
resignAppOperation.resultHandler = { (result) in resignAppOperation.resultHandler = { (result) in
switch result switch result
{ {
case .failure(let error): context.error = error case .failure(let error):
context.error = error
completionHandler(.failure(error))
case .success(let resignedApp): context.resignedApp = resignedApp case .success(let resignedApp): context.resignedApp = resignedApp
} }
} }
@@ -1672,7 +1686,9 @@ private extension AppManager
sendAppOperation.resultHandler = { (result) in sendAppOperation.resultHandler = { (result) in
switch result switch result
{ {
case .failure(let error): context.error = error case .failure(let error):
context.error = error
completionHandler(.failure(error))
case .success(_): print("App reported as installed") case .success(_): print("App reported as installed")
} }
} }
@@ -1757,7 +1773,9 @@ private extension AppManager
fetchProvisioningProfilesOperation.resultHandler = { (result) in fetchProvisioningProfilesOperation.resultHandler = { (result) in
switch result switch result
{ {
case .failure(let error): context.error = error case .failure(let error):
context.error = error
completionHandler(.failure(error))
case .success(let provisioningProfiles): context.provisioningProfiles = provisioningProfiles case .success(let provisioningProfiles): context.provisioningProfiles = provisioningProfiles
} }
} }
@@ -1839,6 +1857,7 @@ private extension AppManager
case .failure(let error): case .failure(let error):
restoreContext.error = error restoreContext.error = error
appContext.error = error appContext.error = error
completionHandler(.failure(error))
} }
} }
restoreAppOperation.addDependency(installBackupAppOperation) restoreAppOperation.addDependency(installBackupAppOperation)
@@ -1960,7 +1979,9 @@ private extension AppManager
backupAppOperation.resultHandler = { (result) in backupAppOperation.resultHandler = { (result) in
switch result switch result
{ {
case .failure(let error): context.error = error case .failure(let error):
context.error = error
completionHandler(.failure(error))
case .success: break case .success: break
} }
} }
@@ -2016,6 +2037,7 @@ private extension AppManager
case .failure(let error): case .failure(let error):
restoreContext.error = error restoreContext.error = error
appContext.error = error appContext.error = error
completionHandler(.failure(error))
} }
} }
backupAppOperation.addDependency(installBackupAppOperation) backupAppOperation.addDependency(installBackupAppOperation)

View File

@@ -126,13 +126,15 @@ final class DownloadAppOperation: ResultOperation<ALTApplication>
override func finish(_ result: Result<ALTApplication, Error>) override func finish(_ result: Result<ALTApplication, Error>)
{ {
do if(FileManager.default.fileExists(atPath: self.temporaryDirectory.path)){
{ do
try FileManager.default.removeItem(at: self.temporaryDirectory) {
} try FileManager.default.removeItem(at: self.temporaryDirectory)
catch }
{ catch
print("Failed to remove DownloadAppOperation temporary directory: \(self.temporaryDirectory).", error) {
print("Failed to remove DownloadAppOperation temporary directory: \(self.temporaryDirectory).", error)
}
} }
super.finish(result) super.finish(result)
@@ -155,54 +157,54 @@ private extension DownloadAppOperation
func download(@Managed _ app: AppProtocol) func download(@Managed _ app: AppProtocol)
{ {
guard let sourceURL = self.sourceURL else { return self.finish(.failure(OperationError.appNotFound(name: self.appName))) guard let sourceURL = self.sourceURL else {
return self.finish(.failure(OperationError.appNotFound(name: self.appName)))
if let appVersion = app as? AppVersion }
if let appVersion = app as? AppVersion
{
// All downloads go through this path, and `app` is
// always an AppVersion if downloading from a source,
// so context.appVersion != nil means downloading from source.
self.context.appVersion = appVersion
}
downloadIPA(from: sourceURL) { result in
do
{ {
// All downloads go through this path, and `app` is let application = try result.get()
// always an AppVersion if downloading from a source,
// so context.appVersion != nil means downloading from source. if self.context.bundleIdentifier == StoreApp.dolphinAppID, self.context.bundleIdentifier != application.bundleIdentifier
self.context.appVersion = appVersion
}
downloadIPA(from: sourceURL!) { result in
do
{ {
let application = try result.get() if var infoPlist = NSDictionary(contentsOf: application.bundle.infoPlistURL) as? [String: Any]
if self.context.bundleIdentifier == StoreApp.dolphinAppID, self.context.bundleIdentifier != application.bundleIdentifier
{ {
if var infoPlist = NSDictionary(contentsOf: application.bundle.infoPlistURL) as? [String: Any] // Manually update the app's bundle identifier to match the one specified in the source.
{ // This allows people who previously installed the app to still update and refresh normally.
// Manually update the app's bundle identifier to match the one specified in the source. infoPlist[kCFBundleIdentifierKey as String] = StoreApp.dolphinAppID
// This allows people who previously installed the app to still update and refresh normally. (infoPlist as NSDictionary).write(to: application.bundle.infoPlistURL, atomically: true)
infoPlist[kCFBundleIdentifierKey as String] = StoreApp.dolphinAppID
(infoPlist as NSDictionary).write(to: application.bundle.infoPlistURL, atomically: true)
}
}
self.downloadDependencies(for: application) { result in
do
{
_ = try result.get()
try FileManager.default.copyItem(at: application.fileURL, to: self.destinationURL, shouldReplace: true)
guard let copiedApplication = ALTApplication(fileURL: self.destinationURL) else { throw OperationError.invalidApp }
self.finish(.success(copiedApplication))
self.progress.completedUnitCount += 1
}
catch
{
self.finish(.failure(error))
}
} }
} }
catch
{ self.downloadDependencies(for: application) { result in
self.finish(.failure(error)) do
{
_ = try result.get()
try FileManager.default.copyItem(at: application.fileURL, to: self.destinationURL, shouldReplace: true)
guard let copiedApplication = ALTApplication(fileURL: self.destinationURL) else { throw OperationError.invalidApp }
self.finish(.success(copiedApplication))
self.progress.completedUnitCount += 1
}
catch
{
self.finish(.failure(error))
}
} }
} }
catch
{
self.finish(.failure(error))
}
} }
func downloadIPA(from sourceURL: URL, completionHandler: @escaping (Result<ALTApplication, Error>) -> Void) func downloadIPA(from sourceURL: URL, completionHandler: @escaping (Result<ALTApplication, Error>) -> Void)
@@ -229,7 +231,7 @@ private extension DownloadAppOperation
} }
defer { defer {
if !sourceURL.isFileURL if !sourceURL.isFileURL && FileManager.default.fileExists(atPath: fileURL.path)
{ {
try? FileManager.default.removeItem(at: fileURL) try? FileManager.default.removeItem(at: fileURL)
} }