Skip to content

Commit 48c131a

Browse files
committed
🔄 synced local 'skyvern/' with remote 'skyvern/'
## Summary - Fix critical bug where `self._page` was used instead of `self.page` in `_wait_for_page_ready_before_action` - **Added diagnostic logging** for screenshot timeouts to help debug Flinks issues ## Bug Fix The `SkyvernPage` class uses `self.page` but `_wait_for_page_ready_before_action` was checking `self._page` which doesn't exist. This caused every cached script action to log: ``` AttributeError: 'ScriptSkyvernPage' object has no attribute '_page' ``` ## Added Logging for Screenshot Diagnostics ### Screenshot timeout now logs context: ``` Screenshot timeout | timeout_ms=3000 | url=https://... | viewport=1920x1080 | full_page=False | mode=detailed ``` ### Scrape retry attempts now logged: ``` Scrape attempt failed, will retry with next strategy | attempt=1 | scrape_type=normal | error_type=FailedToTakeScreenshot | url=... Scrape attempt failed, will retry with next strategy | attempt=2 | scrape_type=normal | error_type=FailedToTakeScreenshot | url=... All scrape attempts failed | total_attempts=3 | error_type=FailedToTakeScreenshot | url=... | step_order=0 | step_retry=1 ``` This will help identify: - **Which URLs** are causing timeouts - **What timeout value** is actually being used - **Page viewport size** (large pages may timeout) - **Which retry attempt** failed - **Step context** (order and retry index) ## Test plan - [ ] Deploy to staging and verify logs appear correctly - [ ] Have Nick deploy and check if new logs provide insight into slowness - [ ] Monitor for patterns in failing URLs/viewport sizes 🤖 Generated with [Claude Code](https://claude.ai/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Use the public page attribute for readiness handling to improve stability when a page is unavailable. * **Chores / Diagnostics** * Enhanced screenshot error/debug logs with URL and viewport info. * Improved scrape retry and failure logs to include attempt counts, error context, and next-step details. * **Tests** * Added unit tests validating readiness behavior and resilience around frame creation and wait routines. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- ELLIPSIS_HIDDEN --> ---- > [!IMPORTANT] > Fix `AttributeError` in `ScriptSkyvernPage` and enhance logging for diagnostics. > > - **Bug Fix**: > - Fix `AttributeError` in `ScriptSkyvernPage._wait_for_page_ready_before_action` by replacing `self._page` with `self.page`. > - **Logging Enhancements**: > - Add detailed logging for screenshot timeouts in `_current_viewpoint_screenshot_helper()` in `page.py`. > - Log scrape retry attempts and failures in `build_and_record_step_prompt()` in `agent.py`. > - **Testing**: > - Add unit tests in `test_script_skyvern_page.py` to verify correct attribute access and exception handling in `_wait_for_page_ready_before_action`. > > <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=Skyvern-AI%2Fskyvern-cloud&utm_source=github&utm_medium=referral)<sup> for cbe137ff395b4ef7b17a3b86bf839e46fc357a1f. You can [customize](https://app.ellipsis.dev/Skyvern-AI/settings/summaries) this summary. It will automatically update as commits are pushed.</sup> <!-- ELLIPSIS_HIDDEN -->
1 parent 6ac311e commit 48c131a

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

skyvern/core/script_generations/script_skyvern_page.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,10 +546,11 @@ async def _wait_for_page_ready_before_action(self) -> None:
546546
3. DOM stability (no significant mutations for 300ms)
547547
"""
548548
try:
549-
if not self._page:
549+
# Note: SkyvernPage uses self.page, not self._page
550+
if not self.page:
550551
return
551552

552-
skyvern_frame = await SkyvernFrame.create_instance(frame=self._page)
553+
skyvern_frame = await SkyvernFrame.create_instance(frame=self.page)
553554
await skyvern_frame.wait_for_page_ready(
554555
network_idle_timeout_ms=settings.PAGE_READY_NETWORK_IDLE_TIMEOUT_MS,
555556
loading_indicator_timeout_ms=settings.PAGE_READY_LOADING_INDICATOR_TIMEOUT_MS,

skyvern/forge/agent.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2456,8 +2456,23 @@ async def build_and_record_step_prompt(
24562456
break
24572457
except (FailedToTakeScreenshot, ScrapingFailed) as e:
24582458
if idx < len(SCRAPE_TYPE_ORDER) - 1:
2459+
LOG.warning(
2460+
"Scrape attempt failed, will retry with next strategy",
2461+
attempt=idx + 1,
2462+
scrape_type=scrape_type.value if hasattr(scrape_type, "value") else str(scrape_type),
2463+
error_type=e.__class__.__name__,
2464+
url=task.url,
2465+
)
24592466
continue
2460-
LOG.exception(f"{e.__class__.__name__} happened in two normal attempts and reload-page retry")
2467+
LOG.error(
2468+
"All scrape attempts failed",
2469+
total_attempts=len(SCRAPE_TYPE_ORDER),
2470+
error_type=e.__class__.__name__,
2471+
url=task.url,
2472+
step_order=step.order,
2473+
step_retry=step.retry_index,
2474+
exc_info=True,
2475+
)
24612476
raise e
24622477

24632478
if scraped_page is None:

skyvern/webeye/utils/page.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ async def _current_viewpoint_screenshot_helper(
7474
) -> bytes:
7575
if page.is_closed():
7676
raise FailedToTakeScreenshot(error_message="Page is closed")
77+
78+
# Capture page context for debugging screenshot issues
79+
url = page.url
80+
try:
81+
viewport = page.viewport_size
82+
viewport_info = f"{viewport['width']}x{viewport['height']}" if viewport else "unknown"
83+
except Exception:
84+
viewport_info = "unknown"
85+
7786
try:
7887
if mode == ScreenshotMode.DETAILED:
7988
await page.wait_for_load_state(timeout=SettingsManager.get_settings().BROWSER_LOADING_TIMEOUT_MS)
@@ -94,10 +103,25 @@ async def _current_viewpoint_screenshot_helper(
94103
)
95104
return screenshot
96105
except TimeoutError as e:
97-
LOG.exception(f"Timeout error while taking screenshot: {str(e)}")
106+
LOG.error(
107+
"Screenshot timeout",
108+
timeout_ms=timeout,
109+
url=url,
110+
viewport=viewport_info,
111+
full_page=full_page,
112+
mode=mode.value if hasattr(mode, "value") else str(mode),
113+
error=str(e),
114+
)
98115
raise FailedToTakeScreenshot(error_message=str(e)) from e
99116
except Exception as e:
100-
LOG.exception(f"Unknown error while taking screenshot: {str(e)}")
117+
LOG.error(
118+
"Screenshot failed",
119+
url=url,
120+
viewport=viewport_info,
121+
full_page=full_page,
122+
error=str(e),
123+
exc_info=True,
124+
)
101125
raise FailedToTakeScreenshot(error_message=str(e)) from e
102126

103127

0 commit comments

Comments
 (0)