Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions packages/narada/src/narada/client.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from __future__ import annotations

import asyncio
import json
import logging
import os
import subprocess
import sys
from dataclasses import dataclass
from http import HTTPStatus
from typing import Any
from uuid import uuid4

Expand All @@ -30,6 +32,7 @@
)
from playwright.async_api import TimeoutError as PlaywrightTimeoutError
from playwright.async_api._context_manager import PlaywrightContextManager
from pydantic import BaseModel, ValidationError
from rich.console import Console

from narada.config import BrowserConfig, ProxyConfig
Expand All @@ -49,6 +52,28 @@ class _LaunchBrowserResult:
side_panel_page: Page


class ApiErrorPayload(BaseModel):
detail: Any | None = None

@classmethod
def from_error_text(cls, error_text: str | None) -> ApiErrorPayload:
if not error_text:
return cls()

try:
return cls.model_validate_json(error_text)
except ValidationError:
try:
body = json.loads(error_text)
except (ValueError, TypeError):
return cls()

if isinstance(body, dict):
return cls(detail=body.get("detail", body))

return cls()
Comment thread
volodymyr-narada marked this conversation as resolved.


class Narada:
_BROWSER_WINDOW_ID_SELECTOR = "#narada-browser-window-id"
_UNSUPPORTED_BROWSER_INDICATOR_SELECTOR = "#narada-unsupported-browser"
Expand Down Expand Up @@ -176,6 +201,15 @@ async def open_and_initialize_cloud_browser_window(
) as resp:
if not resp.ok:
error_text = await resp.text()
if resp.status == HTTPStatus.FORBIDDEN:
error = ApiErrorPayload.from_error_text(error_text)
err = RuntimeError(
f"Failed to create cloud browser session: {resp.status} {error_text}\n"
f"Endpoint URL: {endpoint_url}"
)
err.status_code = resp.status # type: ignore[attr-defined]
err.detail = error.detail # type: ignore[attr-defined]
raise err
raise RuntimeError(
f"Failed to create cloud browser session: {resp.status} {error_text}\n"
f"Endpoint URL: {endpoint_url}"
Expand Down