Skip to content
Open
Show file tree
Hide file tree
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
25 changes: 14 additions & 11 deletions deploy/docker/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ def _attach_declarative_hooks(crawler, hooks_config: dict) -> dict:

logger = logging.getLogger(__name__)


def _raise_for_crawl_failure(result):
if not result.success:
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail=result.error_message,
)


# --- Helper to get memory ---
def _get_memory_mb():
try:
Expand Down Expand Up @@ -147,11 +156,7 @@ async def handle_llm_qa(
enforce_egress(browser_cfg)
crawler = await get_crawler(browser_cfg)
result = await crawler.arun(url)
if not result.success:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=result.error_message
)
_raise_for_crawl_failure(result)
content = result.markdown.fit_markdown or result.markdown.raw_markdown

# Create prompt and get LLM response
Expand Down Expand Up @@ -179,6 +184,8 @@ async def handle_llm_qa(
)

return response.choices[0].message.content
except HTTPException:
raise
except LLMProviderNotAllowed as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
Expand Down Expand Up @@ -389,11 +396,7 @@ async def handle_markdown_request(
)
)

if not result.success:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=result.error_message
)
_raise_for_crawl_failure(result)

return (result.markdown.raw_markdown
if filter_type == FilterType.RAW
Expand Down Expand Up @@ -1023,4 +1026,4 @@ async def _runner():
except HTTPException:
await redis.delete(f"task:{task_id}")
raise
return {"task_id": task_id}
return {"task_id": task_id}
24 changes: 24 additions & 0 deletions deploy/docker/tests/test_api_crawl_failures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import inspect
from types import SimpleNamespace

import pytest
from fastapi import HTTPException

from api import _raise_for_crawl_failure, handle_llm_qa, handle_markdown_request


def test_crawl_failure_is_reported_as_bad_gateway():
result = SimpleNamespace(success=False, error_message="Blocked by anti-bot protection: challenge")

with pytest.raises(HTTPException) as raised:
_raise_for_crawl_failure(result)

assert raised.value.status_code == 502
assert raised.value.detail == result.error_message


@pytest.mark.parametrize("handler", [handle_llm_qa, handle_markdown_request])
def test_single_url_handlers_use_crawl_failure_mapping(handler):
source = inspect.getsource(handler)
assert "_raise_for_crawl_failure(result)" in source
assert handler is not handle_llm_qa or "except HTTPException:" in source
Loading