diff --git a/packages/flutter_tools/lib/src/base/error_handling_io.dart b/packages/flutter_tools/lib/src/base/error_handling_io.dart index 26198839da9..82b8f8561db 100644 --- a/packages/flutter_tools/lib/src/base/error_handling_io.dart +++ b/packages/flutter_tools/lib/src/base/error_handling_io.dart @@ -330,6 +330,16 @@ class ErrorHandlingDirectory ); } + @override + bool existsSync() { + return _runSync( + () => delegate.existsSync(), + platform: _platform, + failureMessage: + 'Flutter failed to check for directory existence at "${delegate.path}"', + ); + } + @override String toString() => delegate.toString(); } diff --git a/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart b/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart index f43bd4588b2..e7dc2df0b36 100644 --- a/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart +++ b/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart @@ -93,6 +93,8 @@ void setupDirectoryMocks({ .thenThrow(FileSystemException('', '', OSError('', errorCode))); when(mockDirectory.deleteSync()) .thenThrow(FileSystemException('', '', OSError('', errorCode))); + when(mockDirectory.existsSync()) + .thenThrow(FileSystemException('', '', OSError('', errorCode))); } void main() { @@ -203,6 +205,20 @@ void main() { expect(() => directory.createSync(recursive: true), throwsToolExit(message: expectedMessage)); }); + + testWithoutContext('when checking for directory existence with permission issues', () async { + setupDirectoryMocks( + mockFileSystem: mockFileSystem, + fs: fs, + errorCode: kUserPermissionDenied, + ); + + final Directory directory = fs.directory('directory'); + + const String expectedMessage = 'Flutter failed to check for directory existence at'; + expect(() => directory.existsSync(), + throwsToolExit(message: expectedMessage)); + }); }); group('throws ToolExit on Linux', () { @@ -298,6 +314,20 @@ void main() { expect(() => directory.createTempSync('prefix'), throwsToolExit(message: expectedMessage)); }); + + testWithoutContext('when checking for directory existence with permission issues', () async { + setupDirectoryMocks( + mockFileSystem: mockFileSystem, + fs: fs, + errorCode: eacces, + ); + + final Directory directory = fs.directory('directory'); + + const String expectedMessage = 'Flutter failed to check for directory existence at'; + expect(() => directory.existsSync(), + throwsToolExit(message: expectedMessage)); + }); }); group('throws ToolExit on macOS', () { @@ -393,6 +423,20 @@ void main() { expect(() => directory.createTempSync('prefix'), throwsToolExit(message: expectedMessage)); }); + + testWithoutContext('when checking for directory existence with permission issues', () async { + setupDirectoryMocks( + mockFileSystem: mockFileSystem, + fs: fs, + errorCode: eacces, + ); + + final Directory directory = fs.directory('directory'); + + const String expectedMessage = 'Flutter failed to check for directory existence at'; + expect(() => directory.existsSync(), + throwsToolExit(message: expectedMessage)); + }); }); testWithoutContext('Caches path context correctly', () {