{"record":{"id":"50d9642854ab7fc6","repo":"abi/screenshot-to-code","slug":"error-taking-screenshot","errorCode":null,"errorMessage":"Error taking screenshot","messagePattern":"Error taking screenshot","errorType":"exception","errorClass":"Exception","httpStatus":500,"severity":"error","filePath":"backend/routes/screenshot.py","lineNumber":73,"sourceCode":"        \"format\": \"png\",\n        \"block_ads\": \"true\",\n        \"block_cookie_banners\": \"true\",\n        \"block_trackers\": \"true\",\n        \"cache\": \"false\",\n        \"viewport_width\": \"342\",\n        \"viewport_height\": \"684\",\n    }\n\n    if device == \"desktop\":\n        params[\"viewport_width\"] = \"1280\"\n        params[\"viewport_height\"] = \"832\"\n\n    async with httpx.AsyncClient(timeout=60) as client:\n        response = await client.get(api_base_url, params=params)\n        if response.status_code == 200 and response.content:\n            return response.content\n        else:\n            raise Exception(\"Error taking screenshot\")\n\n\nclass ScreenshotRequest(BaseModel):\n    url: str\n    apiKey: str\n\n\nclass ScreenshotResponse(BaseModel):\n    url: str\n\n\n@router.post(\"/api/screenshot\")\nasync def app_screenshot(request: ScreenshotRequest):\n    # Extract the URL from the request body\n    url = request.url\n    api_key = request.apiKey\n\n    try:","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/abi/screenshot-to-code/blob/d026163f586dfa8c5c10d28c36edd59a9d3b0e88/backend/routes/screenshot.py#L55-L91","documentation":"Bare Exception(\"Error taking screenshot\") raised inside capture_screenshot() when the screenshotone API returns a non-200 status or an empty body. The check `response.status_code == 200 and response.content` collapses every upstream failure mode — invalid/expired API key, quota exhaustion, blocked or unreachable target URL, upstream 5xx — into one opaque message with no status code or body attached.","triggerScenarios":"GET to api_base_url (screenshotone) with params including url, apiKey, viewport dims returns 401/403 (bad key), 429 (quota), 402 (payment), or 200 with zero-length content (render failure of the target page).","commonSituations":"Expired screenshotone API key; free-tier quota used up; target page blocks headless crawlers or takes longer than the 60s httpx timeout handled elsewhere; api_base_url region endpoint misconfigured.","solutions":["Verify the apiKey param passed to the endpoint is a valid, active screenshotone key","Reproduce the upstream call manually with curl/httpx using the same params and inspect response.status_code and response.text to see the real error","If quota/billing: check the screenshotone dashboard and top up or wait for reset","Improve the raise to include status and body (see exampleFix) so future failures are diagnosable"],"exampleFix":"# before\nif response.status_code == 200 and response.content:\n    return response.content\nelse:\n    raise Exception(\"Error taking screenshot\")\n\n# after\nif response.status_code == 200 and response.content:\n    return response.content\nraise Exception(\n    f\"Screenshot API error: status={response.status_code} body={response.text[:200]}\"\n)","handlingStrategy":"retry","validationCode":"def validate_screenshot_request(url: str, api_key: str) -> None:\n    if not api_key or not api_key.strip():\n        raise ValueError(\"apiKey is required for the screenshot service\")\n    if not is_screenshotable_url(url):\n        raise ValueError(f\"URL not screenshotable: {url}\")","typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    try:\n        return await capture_screenshot(url, api_key)\n    except Exception as e:\n        if str(e) == \"Error taking screenshot\" and attempt == 0:\n            await asyncio.sleep(2); continue  # transient upstream failure, one retry\n        raise","preventionTips":["Keep the screenshotone key valid and monitor quota; a bad key is the most common cause","Log upstream status/body when this fires — the message itself carries no diagnostics","Set an httpx timeout appropriate to slow pages (the client uses 60s)"],"tags":["screenshotone","http-client","api-key","upstream-error"],"backgroundTag":null,"analyzedSha":"d026163f586dfa8c5c10d28c36edd59a9d3b0e88","analyzedAt":"2026-08-14T22:02:06.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}