Firebase keeps reporting issues in my app that look like this:
FileSystemException: Cannot delete file, path = '/data/user/0/<PACKAGE>/cache/libCachedImageData/6cbff3e0-301f-11ea-d72d-0335a490e7f0.png' (OS Error: No such file or directory, errno = 2)
Not really sure what causes them, I have a hard time recreating it too.
I have the same problem
I think that it is related with how flutter_cache_manager manages the cache:
https://pub.dev/packages/flutter_cache_manager#-changelog-tab-
Perhaps it is a good idea to try to upgrade flutter_cache_manager to last version.
I'm having this issue too. My guess is that there is no guarantee that the cache is not cleared by the system. But it is causing a great deal of noise in Crashlytics since every error is unique with the image filename.
That's strange.. The only 2 places where a file is deleted have checks for existence:
var file = new File(p.join(await filePath, cacheObject.relativePath));
if (await file.exists()) {
file.delete();
}
Which version of cached_network_image are you using?
The version I am using is cached_network_image: ^2.0.0.
i have the same problem right now, and using cached_network_image 2.0.0
problem persists in 2.1.0+1
Same problem, both Android and iOS.
The problem caused by cache_store.dart 鈥檚 _cleanupCache (in flutter_cache_manager-1.2.2)
````
Future
final toRemove =
final provider = await _cacheInfoRepository;
final overCapacity = await provider.getObjectsOverCapacity(_capacity);
for (final cacheObject in overCapacity) {
unawaited(_removeCachedFile(cacheObject, toRemove));
}
final oldObjects = await provider.getOldObjects(_maxAge);
for (final cacheObject in oldObjects) {
unawaited(_removeCachedFile(cacheObject, toRemove));
}
await provider.deleteAll(toRemove);
}
```
overCapactiyandoldObjectsare both lists ofCacheObjectto be deleted. In some cases, one file may be deleted twice, and the_removeCachedFile` is an asynchronous function, resulting in a double-delete crash
Future<void> _removeCachedFile(CacheObject cacheObject, List<int> toRemove) async {
// ... more code
final file = (await fileDir).childFile(cacheObject.relativePath);
if (await file.exists()) {
unawaited(file.delete());
}
}
Nice catch @williamtank.
I guess it should be enough to do the removal inside the if (or revert the if)
Current:
Future<void> _removeCachedFile(
CacheObject cacheObject, List<int> toRemove) async {
if (!toRemove.contains(cacheObject.id)) {
toRemove.add(cacheObject.id);
if (_memCache.containsKey(cacheObject.url)) {
_memCache.remove(cacheObject.url);
}
if (_futureCache.containsKey(cacheObject.url)) {
unawaited(_futureCache.remove(cacheObject.url));
}
}
final file = (await fileDir).childFile(cacheObject.relativePath);
if (await file.exists()) {
unawaited(file.delete());
}
}
Proposed:
Future<void> _removeCachedFile(
CacheObject cacheObject, List<int> toRemove) async {
if (!toRemove.contains(cacheObject.id)) {
return;
}
toRemove.add(cacheObject.id);
if (_memCache.containsKey(cacheObject.url)) {
_memCache.remove(cacheObject.url);
}
if (_futureCache.containsKey(cacheObject.url)) {
unawaited(_futureCache.remove(cacheObject.url));
}
final file = (await fileDir).childFile(cacheObject.relativePath);
if (await file.exists()) {
unawaited(file.delete());
}
}
The async only goes async at the first await.
Most helpful comment
The problem caused by cache_store.dart 鈥檚
_cleanupCache(in flutter_cache_manager-1.2.2)```` _cleanupCache() async {[];
Future
final toRemove =
final provider = await _cacheInfoRepository;
}
```
overCapactiyandoldObjectsare both lists ofCacheObjectto be deleted. In some cases, one file may be deleted twice, and the_removeCachedFile` is an asynchronous function, resulting in a double-delete crashFuture<void> _removeCachedFile(CacheObject cacheObject, List<int> toRemove) async { // ... more code final file = (await fileDir).childFile(cacheObject.relativePath); if (await file.exists()) { unawaited(file.delete()); } }