[Windows] Improve symlink ERROR_ACCESS_DENIED error message (#154030)

Currently, if creating a symlink on Windows fails due to `ERROR_ACCESS_DENIED`, you'll get an error message like:

```
Error: ERROR_ACCESS_DENIED file system exception thrown while trying to create a symlink from source to dest
```

The `source` and `dest` paths are incorrect.

This will help us debug: https://github.com/flutter/flutter/issues/153758
This commit is contained in:
Loïc Sharma 2024-08-26 10:52:11 -07:00 committed by GitHub
parent 9032717eac
commit ebfaa45c7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 15 deletions

View File

@ -993,8 +993,8 @@ void _createPlatformPluginSymlinks(Directory symlinkDirectory, List<Object?>? pl
e,
platform: globals.platform,
os: globals.os,
destination: 'dest',
source: 'source',
destination: link.path,
source: path,
);
rethrow;
}

View File

@ -1844,24 +1844,73 @@ The Flutter Preview device does not support the following plugins from your pubs
);
});
testWithoutContext('Symlink ERROR_ACCESS_DENIED failures show developers paths that were used', () async {
final Platform platform = FakePlatform(operatingSystem: 'windows');
final FakeOperatingSystemUtils os = FakeOperatingSystemUtils('Microsoft Windows [Version 10.0.14972.1]');
testUsingContext('Symlink ERROR_ACCESS_DENIED failures show developers paths that were used', () async {
final FakeFlutterProject flutterProject = FakeFlutterProject()
..directory = globals.fs.currentDirectory.childDirectory('app');
final Directory windowsManagedDirectory = flutterProject.directory
.childDirectory('windows')
.childDirectory('flutter');
final FakeWindowsProject windowsProject = FakeWindowsProject()
..managedDirectory = windowsManagedDirectory
..pluginSymlinkDirectory = windowsManagedDirectory
.childDirectory('ephemeral')
.childDirectory('.plugin_symlinks')
..exists = true;
const FileSystemException e = FileSystemException('', '', OSError('', 5));
final File dependenciesFile = flutterProject.directory
.childFile('.flutter-plugins-dependencies');
flutterProject
..flutterPluginsDependenciesFile = dependenciesFile
..windows = windowsProject;
flutterProject.directory.childFile('.packages').createSync(recursive: true);
const String dependenciesFileContents = r'''
{
"plugins": {
"windows": [
{
"name": "some_plugin",
"path": "C:\\some_plugin"
}
]
}
}
''';
dependenciesFile.writeAsStringSync(dependenciesFileContents);
const String expectedMessage =
'ERROR_ACCESS_DENIED file system exception thrown while trying to '
r'create a symlink from C:\some_plugin to '
r'C:\app\windows\flutter\ephemeral\.plugin_symlinks\some_plugin';
expect(
() => handleSymlinkException(
e,
platform: platform,
os: os,
source: pubCachePath,
destination: ephemeralPackagePath,
),
throwsToolExit(
message: 'ERROR_ACCESS_DENIED file system exception thrown while trying to create a symlink from $pubCachePath to $ephemeralPackagePath',
() => createPluginSymlinks(
flutterProject,
featureFlagsOverride: TestFeatureFlags(isWindowsEnabled: true),
),
throwsToolExit(message: expectedMessage),
);
}, overrides: <Type, Generator>{
FileSystem: () {
final FileExceptionHandler handle = FileExceptionHandler();
final ErrorHandlingFileSystem fileSystem = ErrorHandlingFileSystem(
platform: FakePlatform(),
delegate: MemoryFileSystem.test(
style: FileSystemStyle.windows,
opHandle: handle.opHandle,
),
);
const String pluginSymlinkPath = r'C:\app\windows\flutter\ephemeral\.plugin_symlinks\some_plugin';
handle.addError(
fileSystem.link(pluginSymlinkPath),
FileSystemOp.create,
const FileSystemException('', '', OSError('', 5)),
);
return fileSystem;
},
Platform: () => FakePlatform(operatingSystem: 'windows'),
ProcessManager: () => FakeProcessManager.empty(),
});
testWithoutContext('Symlink failures instruct developers to run as administrator on older versions of Windows', () async {