From 19fbe98df3672fdf636a59e57a1dcbeb09e7fc2e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 25 Sep 2020 20:17:39 -0700 Subject: [PATCH] [flutter_tools] pass existsSync through error handling io (#66704) Crash reporting shows at least one instance of EACCES during an existsSync cache call. Add this to the list of error handling io methods. Did not add the async exists method since we lint against its usage. --- .../lib/src/base/error_handling_io.dart | 10 +++++ .../base/error_handling_io_test.dart | 44 +++++++++++++++++++ 2 files changed, 54 insertions(+) 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', () {