From 8e879b066a6823ba7763e490d4f0bf8f7b8e335e Mon Sep 17 00:00:00 2001 From: onevcat Date: Sun, 8 Dec 2019 23:23:57 +0900 Subject: [PATCH] Throw errors when creating cache file failure --- Sources/Cache/DiskStorage.swift | 19 ++++++++++++++++++- Sources/General/KingfisherError.swift | 26 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Sources/Cache/DiskStorage.swift b/Sources/Cache/DiskStorage.swift index 2717010ec..38bdceb36 100644 --- a/Sources/Cache/DiskStorage.swift +++ b/Sources/Cache/DiskStorage.swift @@ -108,6 +108,13 @@ public enum DiskStorage { } let fileURL = cacheFileURL(forKey: key) + do { + try data.write(to: fileURL) + } catch { + throw KingfisherError.cacheError( + reason: .cannotCreateCacheFile(fileURL: fileURL, key: key, data: data, error: error) + ) + } let now = Date() let attributes: [FileAttributeKey : Any] = [ @@ -116,7 +123,17 @@ public enum DiskStorage { // The estimated expiration date. .modificationDate: expiration.estimatedExpirationSinceNow.fileAttributeDate ] - config.fileManager.createFile(atPath: fileURL.path, contents: data, attributes: attributes) + do { + try config.fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path) + } catch { + throw KingfisherError.cacheError( + reason: .cannotSetCacheFileAttribute( + filePath: fileURL.path, + attributes: attributes, + error: error + ) + ) + } } func value(forKey key: String, extendingExpiration: ExpirationExtending = .cacheTime) throws -> T? { diff --git a/Sources/General/KingfisherError.swift b/Sources/General/KingfisherError.swift index feb7494bd..a3262f42d 100644 --- a/Sources/General/KingfisherError.swift +++ b/Sources/General/KingfisherError.swift @@ -100,6 +100,8 @@ public enum KingfisherError: Error { /// - imageNotExisting: The requested image does not exist in cache. Code 3006. /// - cannotConvertToData: Cannot convert an object to data for storing. Code 3007. /// - cannotSerializeImage: Cannot serialize an image to data for storing. Code 3008. + /// - cannotCreateCacheFile: Cannot create the cache file at a certain fileURL under a key. Code 3009. + /// - cannotSetCacheFileAttribute: Cannot set file attributes to a cached file. Code 3010. public enum CacheErrorReason { /// Cannot create a file enumerator for a certain disk URL. Code 3001. @@ -139,6 +141,22 @@ public enum KingfisherError: Error { /// - original: The original image data, if exists. /// - serializer: The `CacheSerializer` used for the image serializing. case cannotSerializeImage(image: KFCrossPlatformImage?, original: Data?, serializer: CacheSerializer) + + /// Cannot create the cache file at a certain fileURL under a key. Code 3009. + /// - fileURL: The url where the cache file should be created. + /// - key: The cache key used for the cache. When caching a file through `KingfisherManager` and Kingfisher's + /// extension method, it is the resolved cache key based on your input `Source` and the image processors. + /// - data: The data to be cached. + /// - error: The underlying error originally thrown by Foundation when writing the `data` to the disk file at + /// `fileURL`. + case cannotCreateCacheFile(fileURL: URL, key: String, data: Data, error: Error) + + /// Cannot set file attributes to a cached file. Code 3010. + /// - filePath: The path of target cache file. + /// - attributes: The file attribute to be set to the target file. + /// - error: The underlying error originally thrown by Foundation when setting the `attributes` to the disk + /// file at `filePath`. + case cannotSetCacheFileAttribute(filePath: String, attributes: [FileAttributeKey : Any], error: Error) } @@ -346,6 +364,12 @@ extension KingfisherError.CacheErrorReason { return "Cannot serialize an image due to the cache serializer returning `nil`. " + "Image: \(String(describing:image)), original data: \(String(describing: originalData)), " + "serializer: \(serializer)." + case .cannotCreateCacheFile(let fileURL, let key, let data, let error): + return "Cannot create cache file at url: \(fileURL), key: \(key), data length: \(data.count). " + + "Underlying foundation error: \(error)." + case .cannotSetCacheFileAttribute(let filePath, let attributes, let error): + return "Cannot set file attribute for the cache file at path: \(filePath), attributes: \(attributes)." + + "Underlying foundation error: \(error)." } } @@ -359,6 +383,8 @@ extension KingfisherError.CacheErrorReason { case .imageNotExisting: return 3006 case .cannotConvertToData: return 3007 case .cannotSerializeImage: return 3008 + case .cannotCreateCacheFile: return 3009 + case .cannotSetCacheFileAttribute: return 3010 } } }