Unverified Commit 44d9af80 authored by Anna Gringauze's avatar Anna Gringauze Committed by GitHub

Flutter_tools for web: report error messages with stacks on exit (#87386)

* Flutter_tools for web platform: report error messages with stacks on toolExit

Print error messages and stacks in verbose mode before calling
`throwToolExit` on communication errors to chrome and dwds.

This will help us disagnose CI flakes:

Helps: https://github.com/flutter/flutter/issues/84012
Closes: https://github.com/flutter/flutter/issues/87149

* Added tests

* Extend timeout for testing failure to connect to chrome

* Update rest of chrome tests to await until matching is finished
parent d1eff7f4
......@@ -314,17 +314,21 @@ class ResidentWebRunner extends ResidentRunner {
enableDevTools: enableDevTools,
);
});
} on WebSocketException {
} on WebSocketException catch (error, stackTrace) {
appFailedToStart();
_logger.printError('$error', stackTrace: stackTrace);
throwToolExit(kExitMessage);
} on ChromeDebugException {
} on ChromeDebugException catch (error, stackTrace) {
appFailedToStart();
_logger.printError('$error', stackTrace: stackTrace);
throwToolExit(kExitMessage);
} on AppConnectionException {
} on AppConnectionException catch (error, stackTrace) {
appFailedToStart();
_logger.printError('$error', stackTrace: stackTrace);
throwToolExit(kExitMessage);
} on SocketException {
} on SocketException catch (error, stackTrace) {
appFailedToStart();
_logger.printError('$error', stackTrace: stackTrace);
throwToolExit(kExitMessage);
} on Exception {
appFailedToStart();
......
......@@ -396,10 +396,11 @@ class ChromiumLauncher {
if (!skipCheck) {
try {
await chrome.chromeConnection.getTabs();
} on Exception catch (e) {
} on Exception catch (error, stackTrace) {
_logger.printError('$error', stackTrace: stackTrace);
await chrome.close();
throwToolExit(
'Unable to connect to Chrome debug port: ${chrome.debugPort}\n $e');
'Unable to connect to Chrome debug port: ${chrome.debugPort}\n $error');
}
}
currentCompleter.complete(chrome);
......
......@@ -942,12 +942,14 @@ void main() {
});
testUsingContext('Successfully turns WebSocketException into ToolExit', () async {
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice);
final BufferLogger logger = BufferLogger.test();
final ResidentRunner residentWebRunner = setUpResidentRunner(flutterDevice, logger: logger);
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
_setupMocks();
webDevFS.exception = const WebSocketException();
await expectLater(residentWebRunner.run, throwsToolExit());
expect(logger.errorText, contains('WebSocketException'));
expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
......
......@@ -62,13 +62,12 @@ void main() {
});
testWithoutContext('can launch chrome and connect to the devtools', () async {
expect(
() async => _testLaunchChrome(
await expectReturnsNormallyLater(
_testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand0',
processManager,
chromeLauncher,
),
returnsNormally,
)
);
});
......@@ -79,13 +78,13 @@ void main() {
chromeLauncher,
);
expect(
() async => _testLaunchChrome(
await expectToolExitLater(
_testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand1',
processManager,
chromeLauncher,
),
throwsToolExit(message: 'Only one instance of chrome can be started'),
contains('Only one instance of chrome can be started'),
);
});
......@@ -97,13 +96,12 @@ void main() {
);
await chrome.close();
expect(
() async => _testLaunchChrome(
await expectReturnsNormallyLater(
_testLaunchChrome(
'/.tmp_rand0/flutter_tools_chrome_device.rand1',
processManager,
chromeLauncher,
),
returnsNormally,
)
);
});
......@@ -219,12 +217,11 @@ void main() {
)
]);
expect(
() async => chromiumLauncher.launch(
await expectReturnsNormallyLater(
chromiumLauncher.launch(
'example_url',
skipCheck: true,
),
returnsNormally,
)
);
});
......@@ -259,12 +256,11 @@ void main() {
)
]);
expect(
() async => chromiumLauncher.launch(
await expectReturnsNormallyLater(
chromiumLauncher.launch(
'example_url',
skipCheck: true,
),
returnsNormally,
)
);
});
......@@ -301,12 +297,11 @@ void main() {
),
]);
expect(
() async => chromiumLauncher.launch(
await expectReturnsNormallyLater(
chromiumLauncher.launch(
'example_url',
skipCheck: true,
),
returnsNormally,
)
);
});
......@@ -322,13 +317,12 @@ void main() {
stderr: kDevtoolsStderr,
));
expect(
() async => chromeLauncher.launch(
await expectReturnsNormallyLater(
chromeLauncher.launch(
'example_url',
skipCheck: true,
debugPort: 10000,
),
returnsNormally,
)
);
});
......@@ -348,13 +342,12 @@ void main() {
stderr: kDevtoolsStderr,
));
expect(
() async => chromeLauncher.launch(
await expectReturnsNormallyLater(
chromeLauncher.launch(
'example_url',
skipCheck: true,
headless: true,
),
returnsNormally,
)
);
});
......@@ -451,13 +444,12 @@ void main() {
stderr: kDevtoolsStderr,
));
expect(
() async => chromeLauncher.launch(
await expectReturnsNormallyLater(
chromeLauncher.launch(
'example_url',
skipCheck: true,
headless: true,
),
returnsNormally,
)
);
});
......@@ -488,13 +480,12 @@ void main() {
stderr: kDevtoolsStderr,
));
expect(
() async => chromeLauncher.launch(
await expectReturnsNormallyLater(
chromeLauncher.launch(
'example_url',
skipCheck: true,
headless: true,
),
returnsNormally,
)
);
});
......@@ -516,15 +507,47 @@ void main() {
));
}
expect(
() async => chromeLauncher.launch(
await expectToolExitLater(
chromeLauncher.launch(
'example_url',
skipCheck: true,
headless: true,
),
throwsToolExit(message: 'Failed to launch browser.'),
contains('Failed to launch browser.'),
);
});
testWithoutContext('Logs an error and exits if connection check fails.', () async {
final BufferLogger logger = BufferLogger.test();
final ChromiumLauncher chromiumLauncher = ChromiumLauncher(
fileSystem: fileSystem,
platform: platform,
processManager: processManager,
operatingSystemUtils: operatingSystemUtils,
browserFinder: findChromeExecutable,
logger: logger,
);
processManager.addCommand(const FakeCommand(
command: <String>[
'example_chrome',
'--user-data-dir=/.tmp_rand0/flutter_tools_chrome_device.rand0',
'--remote-debugging-port=12345',
...kChromeArgs,
'example_url',
],
stderr: kDevtoolsStderr,
));
await expectToolExitLater(
chromiumLauncher.launch(
'example_url',
skipCheck: false,
headless: false,
),
contains('Unable to connect to Chrome debug port:'),
);
expect(logger.errorText, contains('SocketException'));
}, timeout: const Timeout.factor(2));
}
Future<Chromium> _testLaunchChrome(String userDataDir, FakeProcessManager processManager, ChromiumLauncher chromeLauncher) {
......
......@@ -124,6 +124,15 @@ Future<void> expectToolExitLater(Future<dynamic> future, Matcher messageMatcher)
}
}
Future<void> expectReturnsNormallyLater(Future<dynamic> future) async {
try {
await future;
// Catch all exceptions to give a better test failure message.
} catch (e, trace) { // ignore: avoid_catches_without_on_clauses
fail('Expected to run with no exceptions, got $e\n$trace');
}
}
Matcher containsIgnoringWhitespace(String toSearch) {
return predicate(
(String source) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment