From 48b4aa3e93b2a76b89776b0848ab5d60b7271494 Mon Sep 17 00:00:00 2001 From: Ricardo-M-L <69202550+Ricardo-M-L@users.noreply.github.com> Date: Thu, 14 May 2026 13:28:58 +0800 Subject: [PATCH] Fix WebDriver resource leak in HTML-to-PDF conversion (#14310) ### What problem does this PR solve? In `api/utils/web_utils.py`, `__get_pdf_from_html()` creates a Chrome WebDriver but only calls `driver.quit()` inside the `TimeoutException` handler. If the page element becomes stale before the timeout (no exception raised), the WebDriver is never quit, leaking the Chrome browser process and returning `None`. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) ### Changes - Move the PDF printing logic and `driver.quit()` outside the `except` block so they execute on all code paths - Use `try/finally` to ensure `driver.quit()` is always called, even if the `Page.printToPDF` DevTools call fails Co-authored-by: Claude Opus 4.7 --- api/utils/web_utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/utils/web_utils.py b/api/utils/web_utils.py index 23d2421862..e7c1b48f51 100644 --- a/api/utils/web_utils.py +++ b/api/utils/web_utils.py @@ -173,6 +173,9 @@ def __get_pdf_from_html(path: str, timeout: int, install_driver: bool, print_opt try: WebDriverWait(driver, timeout).until(staleness_of(driver.find_element(by=By.TAG_NAME, value="html"))) except TimeoutException: + pass + + try: calculated_print_options = { "landscape": False, "displayHeaderFooter": False, @@ -181,8 +184,9 @@ def __get_pdf_from_html(path: str, timeout: int, install_driver: bool, print_opt } calculated_print_options.update(print_options) result = __send_devtools(driver, "Page.printToPDF", calculated_print_options) - driver.quit() return base64.b64decode(result["data"]) + finally: + driver.quit() def is_valid_url(url: str) -> bool: