-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Discovered while investigating #137168. As of writing this, I believe that resolving this issue is prerequisite to solving that one.
Consider #137168. The crashing exception here is PathNotFoundException: PathNotFoundException: Deletion failed, path = 'D:\<project dir path>\windows\flutter\ephemeral\.plugin_symlinks' (OS Error: The system cannot find the path specified. , errno = 3). However, if we look at the code that threw this, we notice that it confirms the existence of the directory before it tries to delete it.
flutter/packages/flutter_tools/lib/src/flutter_plugins.dart
Lines 1039 to 1042 in 99c7e9f
| if (force && symlinkDirectory.existsSync()) { | |
| // Start fresh to avoid stale links. | |
| symlinkDirectory.deleteSync(recursive: true); | |
| } |
Barring some more complex bug in the tool or Dart's filesystem abstractions, this strongly suggests that something happened to this directory in the time between the tool checking for its existence and trying to delete it.
While it could be argued that this deleteSync call should be replaced a ErrorHandlingFileSystem.deleteIfExists call, this still would not be sufficient to prevent the crash, because deleteIfExists will still throw if it encounters ERROR_PATH_NOT_FOUND:
flutter/packages/flutter_tools/lib/src/base/error_handling_io.dart
Lines 75 to 87 in fda9ecf
| static bool deleteIfExists(FileSystemEntity file, {bool recursive = false}) { | |
| if (!file.existsSync()) { | |
| return false; | |
| } | |
| try { | |
| file.deleteSync(recursive: recursive); | |
| } on FileSystemException catch (err) { | |
| // Certain error codes indicate the file could not be found. It could have | |
| // been deleted by a different program while the tool was running. | |
| // if it still exists, the file likely exists on a read-only volume. | |
| if (err.osError?.errorCode != kSystemCannotFindFile || _noExitOnFailure) { | |
| rethrow; | |
| } |
Notice that if the error code is not kSystemCannotFindFile, we will rethrow. Here is the definition of this constant:
flutter/packages/flutter_tools/lib/src/base/error_handling_io.dart
Lines 24 to 26 in fda9ecf
| /// On windows this is error code 2: ERROR_FILE_NOT_FOUND, and on | |
| /// macOS/Linux it is error code 2/ENOENT: No such file or directory. | |
| const int kSystemCannotFindFile = 2; |
We should augment deleteIfExists to not rethrow in the presence of ERROR_PATH_NOT_FOUND on Windows.