clearAllCaches static method

Future<void> clearAllCaches()

Implementation

static Future<void> clearAllCaches() async {
  try {
    final String appTemporaryPath = await getWebFTemporaryPath();

    // Clear HTTP caches: delete any directory with a name starting with 'HttpCache'
    final Directory tmpDir = Directory(appTemporaryPath);
    if (await tmpDir.exists()) {
      await for (final entity in tmpDir.list(followLinks: false)) {
        if (entity is Directory) {
          final String name = path.basename(entity.path);
          if (name.startsWith('HttpCache')) {
            try {
              await entity.delete(recursive: true);
            } catch (e) {
              // Ignore deletions racing with other processes; log non-ENOENT issues for visibility
              if (e is FileSystemException && e.osError?.errorCode == 2) {
                // ENOENT - already removed
              } else {
                widgetLogger.warning('Failed to remove HTTP cache directory ${entity.path}', e);
              }
            }
          }
        }
      }
    }

    // Clear QuickJS bytecode caches
    final Directory bytecodeCacheDirectory = Directory(
      path.join(appTemporaryPath, 'ByteCodeCaches_${QuickJSByteCodeCache.bytecodeVersion}')
    );
    if (await bytecodeCacheDirectory.exists()) {
      try {
        await bytecodeCacheDirectory.delete(recursive: true);
      } catch (e) {
        // Ignore errors if directory was already deleted by concurrent operation
        if (e is FileSystemException && e.osError?.errorCode == 2) {
          // ENOENT - No such file or directory
          // This is expected in concurrent scenarios
        } else if (e is FileSystemException &&
                   (e.osError?.errorCode == 66 || // ENOTEMPTY - macOS/iOS
                    e.osError?.errorCode == 39)) { // ENOTEMPTY - Linux/Android
          // Directory not empty
          // Try to delete files individually first
          try {
            await for (final entity in bytecodeCacheDirectory.list(recursive: true, followLinks: false)) {
              if (entity is File) {
                try {
                  await entity.delete();
                } catch (fileError) {
                  // Ignore individual file deletion errors
                }
              }
            }
            // Now try to delete the directory again
            await bytecodeCacheDirectory.delete(recursive: true);
          } catch (retryError) {
            // If still failing, log and continue
            widgetLogger.warning('Could not fully clear bytecode cache directory', retryError);
          }
        } else {
          rethrow;
        }
      }
    }

    // Clear memory caches
    HttpCacheController.clearAllMemoryCaches();
    QuickJSByteCodeCache.clearMemoryCache();
  } catch (e, stackTrace) {
    widgetLogger.severe('Error clearing all caches', e, stackTrace);
    rethrow;
  }
}