Repository: servo/servo
File: tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py (Python)

Code before:
        try:
            requests.get(f"http://{self.host}:{self.port}/status", timeout=3)    
        except requests.exceptions.Timeout:
            # FIXME: This indicates a hanged browser. Reasons need to be investigated further.
            self.logger.debug("Servo webdriver status request timed out.")
            return True
        except Exception as e:
            self.logger.debug(f"Servo has shut down normally. {e}")
            return False

        return True

    def stop(self, force=False):
        retry_cnt = 0
        while self.is_alive():
            self.logger.info("Trying to shut down gracefully by extension command")
            try:
                requests.delete(
                    f"http://{self.host}:{self.port}/session/dummy-session-id/servo/shutdown",
                    timeout=3
                )
            except requests.exceptions.ConnectionError:
                self.logger.debug("Browser already shut down (connection refused)")
                break
            except requests.exceptions.RequestException as e:
                self.logger.debug(f"Request exception: {e}")
                break
            except requests.exceptions.Timeout:
                self.logger.debug("Request timed out")
                break
                
            retry_cnt += 1
            if retry_cnt >= self.shutdown_retry:
                self.logger.debug("Max retry exceeded.")
                break
            time.sleep(1)
        super().stop(force)

    def find_wpt_prefs(self, logger):
        default_path = os.path.join("resources", "wpt-prefs.json")
        # The cwd is the servo repo for `./mach test-wpt`, but on WPT runners
        # it is the WPT repo. The nightly tar is extracted inside the Python
        # virtual environment within the repo. This means that on WPT runners,
        # the cwd has the `_venv3/servo` directory inside which we find the
        # binary and the 'resources' directory.
        for dir in [".", "./_venv3/servo"]:
            candidate = os.path.abspath(os.path.join(dir, default_path))
            if os.path.isfile(candidate):
                return candidate
        logger.error("Unable to find wpt-prefs.json")
        return default_path

Review comment (bug):
```suggestion
            except requests.exceptions.RequestException as exception:
                self.logger.debug(f"Request exception: {exception}")
```

Code after:
        try:
            requests.get(f"http://{self.host}:{self.port}/status", timeout=3)    
        except requests.exceptions.Timeout:
            # FIXME: This indicates a hanged browser. Reasons need to be investigated further.
            # It happens with ~0.1% probability in our CI runs.
            self.logger.debug("Servo webdriver status request timed out.")
            return True
        except Exception as exception:
            self.logger.debug(f"Servo has shut down normally. {exception}")
            return False

        return True

    def stop(self, force=False):
        retry_cnt = 0
        while self.is_alive():
            self.logger.info("Trying to shut down gracefully by extension command")
            try:
                requests.delete(
                    f"http://{self.host}:{self.port}/session/dummy-session-id/servo/shutdown",
                    timeout=3
                )
            except requests.exceptions.ConnectionError:
                self.logger.debug("Browser already shut down (connection refused)")
                break
            except requests.exceptions.RequestException as exeception:
                self.logger.debug(f"Request exception: {exeception}")
                break
            except requests.exceptions.Timeout:
                self.logger.debug("Request timed out")
                break
                
            retry_cnt += 1
            if retry_cnt >= self.shutdown_retry_attempts:
                self.logger.warn("Max retry exceeded to normally shut down. Killing instead.")
                break
            time.sleep(1)
        super().stop(force)

    def find_wpt_prefs(self, logger):
        default_path = os.path.join("resources", "wpt-prefs.json")
        # The cwd is the servo repo for `./mach test-wpt`, but on WPT runners
        # it is the WPT repo. The nightly tar is extracted inside the Python
        # virtual environment within the repo. This means that on WPT runners,
        # the cwd has the `_venv3/servo` directory inside which we find the
        # binary and the 'resources' directory.
        for dir in [".", "./_venv3/servo"]:
            candidate = os.path.abspath(os.path.join(dir, default_path))
            if os.path.isfile(candidate):
                return candidate
        logger.error("Unable to find wpt-prefs.json")