Repository navigation
[flutter_tools] Exit cleanly when the WebDriver server cannot create a session - #194207
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
@googlebot I signed it! |
There was a problem hiding this comment.
Code Review
This pull request adds error handling for async_io.WebDriverException in WebDriverService to catch session creation failures, log the error, and throw a tool exit with troubleshooting guidance. It also introduces a corresponding unit test using a fake WebDriver server to verify this behavior. There are no review comments, and I have no feedback to provide.
bkonyi
left a comment
There was a problem hiding this comment.
Thanks for the PR @BilalWalker! Just a couple of comments.
| }, | ||
| ); | ||
|
|
||
| testUsingContext( |
There was a problem hiding this comment.
Can this use testWithoutContext?
There was a problem hiding this comment.
Yes, we can testWithoutContext. Switched to testWithoutContext and construct the service with a FakeToolContext.
| // session. This typically happens when the browser fails to launch, when | ||
| // the browser and WebDriver server versions do not match, or when the | ||
| // session request times out. | ||
| logger.printTrace('$error'); |
There was a problem hiding this comment.
Is this printTrace necessary if we're already including the error in the tool exit below?
There was a problem hiding this comment.
Agreed, removed. Also rebased onto master and adapted to the new DriveTestSpecification signature.
`WebDriverService.startTest` only caught `SocketException` around `createDriver`. When the WebDriver server (chromedriver, safaridriver, geckodriver) was reachable but failed to launch or connect to the browser, `package:webdriver` threw a `WebDriverException` such as `SessionNotCreatedException (500): session not created: DevToolsActivePort file doesn't exist`, which escaped `flutter drive` as an unhandled tool crash. Catch `WebDriverException` as well and turn it into a `ToolExit` that includes the server's error message and points at the usual causes (browser not installed, driver/browser version mismatch, session timeout). Add a regression test that runs a fake WebDriver server which rejects the session request. Fixes flutter#193517
- Drop the redundant printTrace; the error is already included in the ToolExit message. - Use testWithoutContext with a FakeToolContext for the new regression test instead of testUsingContext. - Adapt to the startTest signature change on master, which now takes a DriveTestSpecification.
db9e5f5 to
6614a81
Compare
…a session (flutter#194207) `WebDriverService.startTest` only catches `SocketException` around `async_io.createDriver`. That covers the case where nothing is listening on the driver port, but when the WebDriver server (chromedriver, safaridriver, geckodriver) is reachable and then fails to launch or connect to the browser, `package:webdriver` throws a `WebDriverException` instead, for example: ``` SessionNotCreatedException (500): session not created: DevToolsActivePort file doesn't exist ``` That exception escapes `flutter drive` as an unhandled tool crash. It is the flutter#6 tool crasher in the 3.47.5 crash report (see the linked issue), typically caused by Chrome failing to start, a driver/browser version mismatch, or a Safari session timeout. This PR adds an `on async_io.WebDriverException` clause next to the existing `SocketException` one and turns it into a `ToolExit`. The message includes the server's own error text and points at the usual causes (browser not installed, driver version does not match the browser) plus the existing web integration-test docs link. The existing `SocketException` path is unchanged. Tests: a new test in `web_driver_service_test.dart` starts a loopback `HttpServer` that answers every request with a W3C `session not created` error, points `startTest` at it, and asserts a `ToolExit` containing the server's message. It fails on master (the raw `SessionNotCreatedException` escapes) and passes with this change. Fixes flutter#193517 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [flutter/website]: https://github.com/flutter/website [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…a session (flutter#194207) `WebDriverService.startTest` only catches `SocketException` around `async_io.createDriver`. That covers the case where nothing is listening on the driver port, but when the WebDriver server (chromedriver, safaridriver, geckodriver) is reachable and then fails to launch or connect to the browser, `package:webdriver` throws a `WebDriverException` instead, for example: ``` SessionNotCreatedException (500): session not created: DevToolsActivePort file doesn't exist ``` That exception escapes `flutter drive` as an unhandled tool crash. It is the flutter#6 tool crasher in the 3.47.5 crash report (see the linked issue), typically caused by Chrome failing to start, a driver/browser version mismatch, or a Safari session timeout. This PR adds an `on async_io.WebDriverException` clause next to the existing `SocketException` one and turns it into a `ToolExit`. The message includes the server's own error text and points at the usual causes (browser not installed, driver version does not match the browser) plus the existing web integration-test docs link. The existing `SocketException` path is unchanged. Tests: a new test in `web_driver_service_test.dart` starts a loopback `HttpServer` that answers every request with a W3C `session not created` error, points `startTest` at it, and asserts a `ToolExit` containing the server's message. It fails on master (the raw `SessionNotCreatedException` escapes) and passes with this change. Fixes flutter#193517 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [AI contribution guidelines]: https://github.com/flutter/flutter/blob/main/CONTRIBUTING.ai.md [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [flutter/website]: https://github.com/flutter/website [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
WebDriverService.startTestonly catchesSocketExceptionaroundasync_io.createDriver. That covers the case where nothing is listening on the driver port, but when the WebDriver server (chromedriver, safaridriver, geckodriver) is reachable and then fails to launch or connect to the browser,package:webdriverthrows aWebDriverExceptioninstead, for example:That exception escapes
flutter driveas an unhandled tool crash. It is the #6 tool crasher in the 3.47.5 crash report (see the linked issue), typically caused by Chrome failing to start, a driver/browser version mismatch, or a Safari session timeout.This PR adds an
on async_io.WebDriverExceptionclause next to the existingSocketExceptionone and turns it into aToolExit. The message includes the server's own error text and points at the usual causes (browser not installed, driver version does not match the browser) plus the existing web integration-test docs link. The existingSocketExceptionpath is unchanged.Tests: a new test in
web_driver_service_test.dartstarts a loopbackHttpServerthat answers every request with a W3Csession not createderror, pointsstartTestat it, and asserts aToolExitcontaining the server's message. It fails on master (the rawSessionNotCreatedExceptionescapes) and passes with this change.Fixes #193517
Pre-launch Checklist
///).