diff --git a/.changeset/review-apple-io.md b/.changeset/review-apple-io.md new file mode 100644 index 00000000..754d0682 --- /dev/null +++ b/.changeset/review-apple-io.md @@ -0,0 +1,6 @@ +--- +"@react-native-async-storage/async-storage": patch +--- + +Keep manifest entries on file read errors and cache large values only after successful writes. + diff --git a/packages/async-storage/apple/legacy_storage/RNCAsyncStorage.mm b/packages/async-storage/apple/legacy_storage/RNCAsyncStorage.mm index d9f3dc82..611e0fd9 100644 --- a/packages/async-storage/apple/legacy_storage/RNCAsyncStorage.mm +++ b/packages/async-storage/apple/legacy_storage/RNCAsyncStorage.mm @@ -603,9 +603,14 @@ - (NSString *)_getValueForKey:(NSString *)key errorOut:(NSDictionary *__autorele value = [RCTGetCache() objectForKey:key]; if (!value) { NSString *filePath = [self _filePathForKey:key]; - value = RCTReadFile(filePath, key, errorOut); + NSDictionary *readError = nil; + value = RCTReadFile(filePath, key, &readError); if (value) { [RCTGetCache() setObject:value forKey:key cost:value.length]; + } else if (readError) { + if (errorOut) { + *errorOut = readError; + } } else { // file does not exist after all, so remove from manifest (no need to save // manifest immediately though, as cost of checking again next time is negligible) @@ -641,12 +646,14 @@ - (NSDictionary *)_writeEntry:(NSArray *)entry changedManifest:(BOOL return nil; } [value writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error]; - [RCTGetCache() setObject:value forKey:key cost:value.length]; if (error) { errorOut = RCTMakeError(@"Failed to write value.", error, @{@"key": key}); - } else if (_manifest[key] != (id)kCFNull) { - *changedManifest = YES; - _manifest[key] = (id)kCFNull; + } else { + [RCTGetCache() setObject:value forKey:key cost:value.length]; + if (_manifest[key] != (id)kCFNull) { + *changedManifest = YES; + _manifest[key] = (id)kCFNull; + } } return errorOut; }