From b6721206bf08c16309bad1747ab79d3ad4c77fca Mon Sep 17 00:00:00 2001 From: Peter Rehm Date: Wed, 31 Jan 2018 12:44:42 +0100 Subject: [PATCH] Improved error handling when Chrome Connection can not be established and provided hints. --- docs/troubleshooting.md | 11 +++++++++++ src/ChromeBrowser.php | 2 +- src/ChromePage.php | 9 +++++++++ src/DevToolsConnection.php | 16 ++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 docs/troubleshooting.md diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..81cd059 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,11 @@ +Troubleshooting +=============== + +1. Chrome Crashed unexpectedly +------------------------------ + +When the shm size is too low, chrome is likely to crash randomly. +The solution is increasing SHM size until the crashes no longer occur (or mounting /dev/shm:/dev/shm to the container) +Sometimes increasing SHM size is not possible (gitlab.com shared runners, for example gitlab-org/gitlab-runner#1454 +Running with vendor/bin/behat --rerun || vendor/bin/behat --rerun is a good workaround for this and other hiccups. +Since it'll cause behat to rerun only the failed scenarios and only fail the build if they fail again. diff --git a/src/ChromeBrowser.php b/src/ChromeBrowser.php index ee577df..0b019ad 100644 --- a/src/ChromeBrowser.php +++ b/src/ChromeBrowser.php @@ -44,7 +44,7 @@ public function start() if (null === $versionInfo) { throw new \RuntimeException( sprintf( - 'Could not fetch version information from %s. Please check if Chrome is running.', + 'Could not fetch version information from %s. Please check if Chrome is running. Please see docs/troubleshooting.md if Chrome crashed unexpected.', $this->http_uri.'/json/version' ) ); diff --git a/src/ChromePage.php b/src/ChromePage.php index 05ef27e..2d65200 100644 --- a/src/ChromePage.php +++ b/src/ChromePage.php @@ -56,6 +56,15 @@ public function waitForLoad() return $this->page_ready; }); } catch (StreamReadException $exception) { + if ($exception->isTimedOut() && false === $this->canDevToolsConnectionBeEstablished()) { + throw new \RuntimeException( + sprintf( + 'Chrome is unreachable via "%s" and might have crashed. Please see docs/troubleshooting.md', + $this->getUrl() + ) + ); + } + if (!$exception->isEof() && $exception->isTimedOut()) { $this->waitForLoad(); } diff --git a/src/DevToolsConnection.php b/src/DevToolsConnection.php index 0b4b61d..211d5f3 100644 --- a/src/DevToolsConnection.php +++ b/src/DevToolsConnection.php @@ -22,6 +22,22 @@ public function __construct($url, $socket_timeout = null) $this->socket_timeout = $socket_timeout; } + public function canDevToolsConnectionBeEstablished() + { + $options = ['fragment_size' => 2000000]; # Chrome closes the connection if a message is sent in fragments + if (is_numeric($this->socket_timeout) && $this->socket_timeout > 0) { + $options['timeout'] = (int) $this->socket_timeout; + } + $client = new Client($this->url, $options); + + return $client->isConnected(); + } + + protected function getUrl() + { + return $this->url; + } + public function connect($url = null) { $url = $url == null ? $this->url : $url;