Explorar o código

Error handling in FileStorage

polscm32 hai 1 ano
pai
achega
4a0dbeb62d

+ 2 - 2
Trio/Sources/Application/TrioApp.swift

@@ -80,7 +80,7 @@ import Swinject
 
             // Fix bug in iOS 18 related to the translucent tab bar
             configureTabBarAppearance()
-            
+
             // Clear the persistentHistory and the NSManagedObjects that are older than 90 days every time the app starts
             cleanupOldData()
         } catch {
@@ -140,7 +140,7 @@ import Swinject
         do {
             try BGTaskScheduler.shared.submit(request)
             debug(.coreData, "Task for cleaning database scheduled successfully")
-        } catch let error {
+        } catch {
             debug(.coreData, "Failed to schedule tasks for cleaning database: \(error.localizedDescription)")
         }
     }

+ 4 - 0
Trio/Sources/Logger/Logger.swift

@@ -116,6 +116,7 @@ final class Logger {
     static let bolusState = Logger(category: .bolusState, reporter: baseReporter)
     static let watchManager = Logger(category: .watchManager, reporter: baseReporter)
     static let coreData = Logger(category: .coreData, reporter: baseReporter)
+    static let storage = Logger(category: .storage, reporter: baseReporter)
 
     enum Category: String {
         case `default`
@@ -129,6 +130,7 @@ final class Logger {
         case bolusState
         case watchManager
         case coreData
+        case storage
 
         var name: String {
             rawValue.capitalizingFirstLetter()
@@ -147,6 +149,7 @@ final class Logger {
             case .bolusState: return .bolusState
             case .watchManager: return .watchManager
             case .coreData: return .coreData
+            case .storage: return .storage
             }
         }
 
@@ -163,6 +166,7 @@ final class Logger {
                  .openAPS,
                  .remoteControl,
                  .service,
+                 .storage,
                  .watchManager:
                 return OSLog(subsystem: subsystem, category: name)
             }

+ 74 - 21
Trio/Sources/Services/Storage/FileStorage.swift

@@ -23,10 +23,14 @@ final class BaseFileStorage: FileStorage {
 
     func save<Value: JSON>(_ value: Value, as name: String) {
         processQueue.safeSync {
-            if let value = value as? RawJSON, let data = value.data(using: .utf8) {
-                try? Disk.save(data, to: .documents, as: name)
-            } else {
-                try? Disk.save(value, to: .documents, as: name, encoder: JSONCoding.encoder)
+            do {
+                if let value = value as? RawJSON, let data = value.data(using: .utf8) {
+                    try Disk.save(data, to: .documents, as: name)
+                } else {
+                    try Disk.save(value, to: .documents, as: name, encoder: JSONCoding.encoder)
+                }
+            } catch {
+                debug(.storage, "Failed to save file '\(name)': \(error.localizedDescription)")
             }
         }
     }
@@ -34,10 +38,14 @@ final class BaseFileStorage: FileStorage {
     func saveAsync<Value: JSON>(_ value: Value, as name: String) async {
         await withCheckedContinuation { continuation in
             processQueue.safeSync {
-                if let value = value as? RawJSON, let data = value.data(using: .utf8) {
-                    try? Disk.save(data, to: .documents, as: name)
-                } else {
-                    try? Disk.save(value, to: .documents, as: name, encoder: JSONCoding.encoder)
+                do {
+                    if let value = value as? RawJSON, let data = value.data(using: .utf8) {
+                        try Disk.save(data, to: .documents, as: name)
+                    } else {
+                        try Disk.save(value, to: .documents, as: name, encoder: JSONCoding.encoder)
+                    }
+                } catch {
+                    debug(.storage, "Failed to save file '\(name)': \(error.localizedDescription)")
                 }
                 continuation.resume()
             }
@@ -46,49 +54,81 @@ final class BaseFileStorage: FileStorage {
 
     func retrieve<Value: JSON>(_ name: String, as type: Value.Type) -> Value? {
         processQueue.safeSync {
-            try? Disk.retrieve(name, from: .documents, as: type, decoder: JSONCoding.decoder)
+            do {
+                return try Disk.retrieve(name, from: .documents, as: type, decoder: JSONCoding.decoder)
+            } catch {
+                debug(.storage, "Failed to retrieve file '\(name)': \(error.localizedDescription)")
+                return nil
+            }
         }
     }
 
     func retrieveAsync<Value: JSON>(_ name: String, as type: Value.Type) async -> Value? {
         await withCheckedContinuation { continuation in
             processQueue.safeSync {
-                let result = try? Disk.retrieve(name, from: .documents, as: type, decoder: JSONCoding.decoder)
-                continuation.resume(returning: result)
+                do {
+                    let result = try Disk.retrieve(name, from: .documents, as: type, decoder: JSONCoding.decoder)
+                    continuation.resume(returning: result)
+                } catch {
+                    debug(.storage, "Failed to retrieve file '\(name)': \(error.localizedDescription)")
+                    continuation.resume(returning: nil)
+                }
             }
         }
     }
 
     func retrieveRaw(_ name: String) -> RawJSON? {
         processQueue.safeSync {
-            guard let data = try? Disk.retrieve(name, from: .documents, as: Data.self) else {
+            do {
+                let data = try Disk.retrieve(name, from: .documents, as: Data.self)
+                guard let string = String(data: data, encoding: .utf8) else {
+                    debug(.storage, "Failed to decode data as UTF-8 string for file '\(name)'")
+                    return nil
+                }
+                return string
+            } catch {
+                debug(.storage, "Failed to retrieve file '\(name)': \(error.localizedDescription)")
                 return nil
             }
-            return String(data: data, encoding: .utf8)
         }
     }
 
     func retrieveRawAsync(_ name: String) async -> RawJSON? {
         await withCheckedContinuation { continuation in
             processQueue.safeSync {
-                guard let data = try? Disk.retrieve(name, from: .documents, as: Data.self) else {
+                do {
+                    let data = try Disk.retrieve(name, from: .documents, as: Data.self)
+                    guard let string = String(data: data, encoding: .utf8) else {
+                        debug(.storage, "Failed to decode data as UTF-8 string for file '\(name)'")
+                        continuation.resume(returning: nil)
+                        return
+                    }
+                    continuation.resume(returning: string)
+                } catch {
+                    debug(.storage, "Failed to retrieve file '\(name)': \(error.localizedDescription)")
                     continuation.resume(returning: nil)
-                    return
                 }
-                continuation.resume(returning: String(data: data, encoding: .utf8))
             }
         }
     }
 
     func append<Value: JSON>(_ newValue: Value, to name: String) {
         processQueue.safeSync {
-            try? Disk.append(newValue, to: name, in: .documents, decoder: JSONCoding.decoder, encoder: JSONCoding.encoder)
+            do {
+                try Disk.append(newValue, to: name, in: .documents, decoder: JSONCoding.decoder, encoder: JSONCoding.encoder)
+            } catch {
+                debug(.storage, "Failed to append to file '\(name)': \(error.localizedDescription)")
+            }
         }
     }
 
     func append<Value: JSON>(_ newValues: [Value], to name: String) {
         processQueue.safeSync {
-            try? Disk.append(newValues, to: name, in: .documents, decoder: JSONCoding.decoder, encoder: JSONCoding.encoder)
+            do {
+                try Disk.append(newValues, to: name, in: .documents, decoder: JSONCoding.decoder, encoder: JSONCoding.encoder)
+            } catch {
+                debug(.storage, "Failed to append to file '\(name)': \(error.localizedDescription)")
+            }
         }
     }
 
@@ -130,13 +170,21 @@ final class BaseFileStorage: FileStorage {
 
     func remove(_ name: String) {
         processQueue.safeSync {
-            try? Disk.remove(name, from: .documents)
+            do {
+                try Disk.remove(name, from: .documents)
+            } catch {
+                debug(.storage, "Failed to remove file '\(name)': \(error.localizedDescription)")
+            }
         }
     }
 
     func rename(_ name: String, to newName: String) {
         processQueue.safeSync {
-            try? Disk.rename(name, in: .documents, to: newName)
+            do {
+                try Disk.rename(name, in: .documents, to: newName)
+            } catch {
+                debug(.storage, "Failed to rename file '\(name)' to '\(newName)': \(error.localizedDescription)")
+            }
         }
     }
 
@@ -147,7 +195,12 @@ final class BaseFileStorage: FileStorage {
     }
 
     func urlFor(file: String) -> URL? {
-        try? Disk.url(for: file, in: .documents)
+        do {
+            return try Disk.url(for: file, in: .documents)
+        } catch {
+            debug(.storage, "Failed to get URL for file '\(file)': \(error.localizedDescription)")
+            return nil
+        }
     }
 }