diff --git a/packages/flutter_tools/lib/src/web/chrome.dart b/packages/flutter_tools/lib/src/web/chrome.dart index 90af6e5cf8..996d79c468 100644 --- a/packages/flutter_tools/lib/src/web/chrome.dart +++ b/packages/flutter_tools/lib/src/web/chrome.dart @@ -507,8 +507,14 @@ class Chromium { // Send a command to shut down the browser cleanly. Duration sigtermDelay = Duration.zero; if (_hasValidChromeConnection) { - final ChromeTab? tab = await chromeConnection.getTab( - (_) => true, retryFor: const Duration(seconds: 1)); + ChromeTab? tab; + try { + tab = await chromeConnection.getTab( + (_) => true, retryFor: const Duration(seconds: 1)); + } on SocketException { + // Chrome is not responding to the debug protocol and probably has + // already been closed. + } if (tab != null) { final WipConnection wipConnection = await tab.connect(); await wipConnection.sendCommand('Browser.close'); diff --git a/packages/flutter_tools/test/web.shard/chrome_test.dart b/packages/flutter_tools/test/web.shard/chrome_test.dart index 08bc8a0502..a7cf10c786 100644 --- a/packages/flutter_tools/test/web.shard/chrome_test.dart +++ b/packages/flutter_tools/test/web.shard/chrome_test.dart @@ -820,6 +820,24 @@ void main() { await chrome.close(); expect(commands, contains('Browser.close')); }); + + test('Chromium close handles a SocketException when connecting to Chrome', () async { + final BufferLogger logger = BufferLogger.test(); + final FakeChromeConnectionWithTab chromeConnection = FakeChromeConnectionWithTab(); + final ChromiumLauncher chromiumLauncher = ChromiumLauncher( + fileSystem: fileSystem, + platform: platform, + processManager: processManager, + operatingSystemUtils: operatingSystemUtils, + browserFinder: findChromeExecutable, + logger: logger, + ); + final FakeProcess process = FakeProcess(); + final Chromium chrome = Chromium(0, chromeConnection, chromiumLauncher: chromiumLauncher, process: process, logger: logger); + expect(await chromiumLauncher.connect(chrome, false), equals(chrome)); + chromeConnection.throwSocketExceptions = true; + await chrome.close(); + }); } /// Fake chrome connection that fails to get tabs a few times. @@ -863,14 +881,21 @@ class FakeChromeConnectionWithTab extends Fake implements ChromeConnection { : _tab = FakeChromeTab(onSendCommand); final FakeChromeTab _tab; + bool throwSocketExceptions = false; @override Future getTab(bool Function(ChromeTab tab) accept, {Duration? retryFor}) async { + if (throwSocketExceptions) { + throw const io.SocketException('test'); + } return _tab; } @override Future> getTabs({Duration? retryFor}) async { + if (throwSocketExceptions) { + throw const io.SocketException('test'); + } return [_tab]; }