From 37d80ce25f68682041b067db77229e0ee93d4e71 Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Tue, 12 Nov 2024 10:14:45 -0800 Subject: [PATCH] add filesystem error handling to `systemTempDirectory` (#158481) Fixes https://github.com/flutter/flutter/issues/153777. To summarize that issue, `ErrorHandlingFileSystem.systemTempDirectory` calls [`LocalFileSystem.systemTempDirectory`](https://github.com/flutter/flutter/blob/45c8881eb289e3b68e890cefa0acd13dbf800147/packages/flutter_tools/lib/src/base/file_system.dart#L229), which makes a `Directory.createSync` call, which can throw exceptions that _should_ be handled and result in a graceful tool exit (e.g. insufficient storage). However, we aren't catching those, hence this issue. All we need to do is wrap that call with the `FileSystemException`-handling logic we already have in the tool. See the diff. I don't think I'll be cherry-picking this since 1) it's not an extremely common crash and 2) users can probably pick apart the crash message and figure out that they need to clear some storage space to proceed.
Pre-launch checklist
--- .../lib/src/base/error_handling_io.dart | 2 +- .../base/error_handling_io_test.dart | 31 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) 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 41bc27e8859..e7086141d92 100644 --- a/packages/flutter_tools/lib/src/base/error_handling_io.dart +++ b/packages/flutter_tools/lib/src/base/error_handling_io.dart @@ -124,7 +124,7 @@ class ErrorHandlingFileSystem extends ForwardingFileSystem { @override Directory get systemTempDirectory { - return directory(delegate.systemTempDirectory); + return _runSync(() => directory(delegate.systemTempDirectory), platform: _platform); } @override 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 a43367c3419..c4b661dfaa6 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 @@ -884,7 +884,7 @@ void main() { }); }); - testWithoutContext("ErrorHandlingFileSystem.systemTempDirectory wraps delegates filesystem's systemTempDirectory", () { + testWithoutContext("ErrorHandlingFileSystem.systemTempDirectory wraps delegate filesystem's systemTempDirectory", () { final FileExceptionHandler exceptionHandler = FileExceptionHandler(); final MemoryFileSystem delegate = MemoryFileSystem.test( @@ -921,6 +921,35 @@ Please ensure that the SDK and/or project is installed in a location that has re ); }); + testWithoutContext("ErrorHandlingFileSystem.systemTempDirectory handles any exception thrown by the delegate's systemTempDirectory implementation", () { + final FileExceptionHandler exceptionHandler = FileExceptionHandler(); + exceptionHandler.addTempError( + FileSystemOp.create, + const FileSystemException( + 'Creation of temporary directory failed', + 'some/temp/path', + OSError( + 'No space left on device', + 28, + ), + ), + ); + + final MemoryFileSystem delegate = MemoryFileSystem.test( + opHandle: exceptionHandler.opHandle, + ); + + final FileSystem fs = ErrorHandlingFileSystem( + delegate: delegate, + platform: FakePlatform(), + ); + + expect( + () => fs.systemTempDirectory, + throwsToolExit(message: 'Free up space and try again.'), + ); + }); + group('ProcessManager on windows throws tool exit', () { const int kDeviceFull = 112; const int kUserMappedSectionOpened = 1224;