Skip to content

fix(browser): report persistent screencast capture failures - #2088

Open
chqcjq wants to merge 1 commit into
TencentCloud:developfrom
chqcjq:codex/fix-browser-capture-failure-status
Open

chqcjq wants to merge 1 commit into
TencentCloud:developfrom
chqcjq:codex/fix-browser-capture-failure-status

Conversation

@chqcjq

@chqcjq chqcjq commented Oct 15, 2026

Copy link
Copy Markdown

Summary

Related #2083 — fixes the Octop server's silent capture-failure/status bug described in the report. The GPU compositor hang / virtual-display launcher policy in octop-browser is outside this patch; this PR intentionally does not close that issue.

_capture_jpeg() already bounds each screenshot attempt and returns None on failure, but _stream_loop() always advertises streaming and keeps retrying without any visible failure signal. A stuck compositor therefore leaves the viewer blank while the UI claims the stream is healthy and production logs contain no warning.

Track consecutive failed captures in this connection's stream loop:

  • On the third consecutive failure, emit the existing status=error wire message and log one warning identifying the profile.
  • Keep retrying without logging on every tick. Short failure sequences reset on the next successful frame.
  • Once capture succeeds after an error, send status=streaming before the frame and reset the failure count. A later independent failure episode can report its own error.
  • Listen-only connections do not capture frames and do not report capture errors.

The existing dashboard hook/viewer already handles these status messages and displays its localized error/reconnect UI, so there is no new frontend production logic or user-facing string. Includes one Unreleased CHANGELOG line.

Issue and existing PR checks

Verification

Windows / Python 3.12 / frozen uv.lock:

  • Red before fix: new backend regressions gave 2 failed / 2 passed. Repeated CDP timeouts never produced an error status; recovery sequences had no error/recovery transitions.
  • Green: uv run --no-sync python -m pytest tests/unit/api/test_browser_stream_capture.py tests/unit/api/test_browser_stream_listen.py tests/unit/api/test_browser_stream_mouse.py tests/unit/api/test_browser_stream_normalize_nav.py -q — 20 passed. Exercises the real capture helper with synthetic CDP timeouts / empty results / frames, and verifies wire statuses, one warning per failure episode, resets, recovery and listen-only behavior.
  • npx vitest run src/hooks/useBrowserStream.status.test.tsx — 1 passed. Renders the actual useBrowserStream + BrowserViewer, delivers WebSocket status messages, checks the existing failure/reconnect UI and recovery on the same connection.
  • npx tsc -b and ESLint on the new frontend test — passed.
  • Local Codex CLI static review of the complete patch and relevant backend/frontend code — completed with no actionable findings. Tests were executed separately.
  • make all RUN="uv run --no-sync python -m" PYTEST_JOBS=8 (ASCII path overrides for the Windows checkout) — passed: format/lint, mypy, 4607 passed / 209 skipped backend tests.
  • Normal Git pre-commit hook (not bypassed) — passed: format/lint/mypy, 37 passed affected tests, and TypeScript + Vite/PWA production build.

These are deterministic tests; no claim is made to have reproduced an AMD/NVIDIA GPU hang on this Windows machine. The launcher/GPU root cause remains for the browser package. Remote CI remains separate from local verification.

Target branch

  • develop
  • Focused fix, backend/frontend regression coverage, Unreleased CHANGELOG

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant