Timeout Handling Notes
- API request timeout protects against hung local services.
- CDP timeout protects browser connection stage.
- Page timeout protects navigation/action stages.
This guide focuses on the full operational path: deterministic profile launch, CDP connection reliability, error taxonomy, and guaranteed resource cleanup.
Before You Start
Do not start load tests before preflight checks pass. Most rollout instability starts with missing preflight discipline.
Endpoint Sanity Check
curl "http://127.0.0.1:35000/api/v1/profile/start?automation=true&profileId=YOUR_PROFILE_ID"
Expected response should include automation.remote_debugging_address. If missing, do not proceed to Playwright connect.
Architecture
/api/v1/profile/start?automation=true and extract remote_debugging_address.chromium.connect_over_cdp with explicit connect timeout.finally to prevent orphan sessions.Use the local endpoint to boot a profile in automation mode and return a CDP address.
GET /api/v1/profile/start?automation=true&profileId={PROFILE_ID}
Expected key: automation.remote_debugging_address
import logging
import requests
from playwright.sync_api import sync_playwright
from playwright.sync_api import TimeoutError as PWTimeout
API_BASE = "http://127.0.0.1:35000"
LOGGER = logging.getLogger("mlg-playwright")
def start_profile(profile_id: str, timeout: int = 60) -> str:
url = f"{API_BASE}/api/v1/profile/start"
params = {"automation": "true", "profileId": profile_id}
resp = requests.get(url, params=params, timeout=timeout)
resp.raise_for_status()
data = resp.json()
cdp = data.get("automation", {}).get("remote_debugging_address")
if not cdp:
raise RuntimeError(f"Missing remote_debugging_address: {data}")
return cdp if cdp.startswith("http") else f"http://{cdp}"
def stop_profile(profile_id: str, timeout: int = 30) -> None:
url = f"{API_BASE}/api/v1/profile/stop"
requests.get(url, params={"profileId": profile_id}, timeout=timeout)
def run_task(profile_id: str, target_url: str) -> None:
browser = None
try:
cdp = start_profile(profile_id)
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(cdp, timeout=45000)
context = browser.contexts[0] if browser.contexts else browser.new_context()
page = context.pages[0] if context.pages else context.new_page()
page.set_default_timeout(45000)
page.goto(target_url, wait_until="domcontentloaded")
LOGGER.info("Profile %s landed on: %s", profile_id, page.url)
# Add your deterministic assertions here.
except requests.Timeout as exc:
LOGGER.error("API timeout for %s: %s", profile_id, exc)
except PWTimeout as exc:
LOGGER.error("Browser timeout for %s: %s", profile_id, exc)
except Exception as exc:
LOGGER.exception("Unexpected automation error for %s: %s", profile_id, exc)
finally:
try:
if browser is not None:
browser.close()
finally:
stop_profile(profile_id)
Always enforce finally cleanup so profiles are stopped even when a script fails.
Common Setup Mistakes
Skipping API reachability checks causes avoidable retries and noisy incident logs.
Default timeouts hide where failures occur, making root-cause analysis slower.
Missing stop-profile logic leaves orphan sessions and corrupts later runs.
Failure Catalog
| Symptom | Likely cause | Fast action |
|---|---|---|
| No remote_debugging_address in response | Profile startup failed or payload shape changed | Log full JSON response and validate profile state before connect. |
| CDP connect timeout | Local engine not fully ready | Retry with bounded backoff and monitor profile boot latency. |
| Script exits but profile stays alive | Cleanup path not guaranteed | Use nested finally blocks and add stop-profile error logging. |
| HTTP 4xx from start endpoint | Invalid profile ID or auth/session context issue | Validate profile identifier and local API session state before retry. |
| HTTP 5xx from local API | Local service instability or backend transient error | Apply capped retries and collect service health logs for diagnosis. |
| Page actions fail despite successful connect | Context or page handle not initialized as expected | Guard context and page creation path and assert handle availability. |
| Intermittent timeout spikes | Resource contention or unstable proxy path | Capture proxy and host metrics per run and isolate noisy environments. |
| Unexpected payload keys after update | API response shape changed between versions | Log schema snapshot, add fallback parser, and pin compatibility assumptions. |
Compatibility Notes
Pre-Scale Checklist
For account-critical operations, run this checklist before each major browser or proxy stack change.
Stack Strategy Layer
This API guide solves launch and lifecycle reliability. For deeper decisions across Puppeteer, Playwright, Selenium, and request-level libraries, use the dedicated architecture playbook.
FAQ
Start profile with automation enabled, connect over CDP with timeout, execute work, and enforce stop profile in a guaranteed cleanup block.
Most failures are caused by weak timeout policies, missing payload validation, and incomplete cleanup branches.
Run repeated sessions, compare stability signals, and confirm deterministic logs for every profile lifecycle event.
Pause when critical failures repeat, cleanup status is inconsistent, or payload assumptions change unexpectedly.
Yes. Use ops-level go or no-go gates so buying or scaling decisions happen after stable repeated-session evidence.