Better exception handling
This commit is contained in:
parent
49f9843db3
commit
41f694d377
2 changed files with 68 additions and 16 deletions
|
|
@ -304,13 +304,9 @@ class HaikuRAG:
|
|||
"Return ONLY the title text, nothing else."
|
||||
),
|
||||
)
|
||||
try:
|
||||
result = await agent.run(truncated)
|
||||
title = result.output.strip()
|
||||
return title if title else None
|
||||
except Exception:
|
||||
logger.warning("LLM title generation failed", exc_info=True)
|
||||
return None
|
||||
result = await agent.run(truncated)
|
||||
title = result.output.strip()
|
||||
return title if title else None
|
||||
|
||||
async def _resolve_title(
|
||||
self,
|
||||
|
|
@ -335,7 +331,13 @@ class HaikuRAG:
|
|||
if structural:
|
||||
return structural
|
||||
|
||||
return await self._generate_title_with_llm(content)
|
||||
try:
|
||||
return await self._generate_title_with_llm(content)
|
||||
except Exception:
|
||||
logger.warning(
|
||||
"LLM title generation failed during ingestion", exc_info=True
|
||||
)
|
||||
return None
|
||||
|
||||
async def generate_title(self, document: Document) -> str | None:
|
||||
"""Generate a title for a document.
|
||||
|
|
@ -1691,7 +1693,13 @@ class HaikuRAG:
|
|||
if doc.title is not None:
|
||||
continue
|
||||
assert doc.id is not None
|
||||
title = await self.generate_title(doc)
|
||||
try:
|
||||
title = await self.generate_title(doc)
|
||||
except Exception:
|
||||
logger.warning(
|
||||
"Failed to generate title for document %s", doc.id, exc_info=True
|
||||
)
|
||||
continue
|
||||
if title is not None:
|
||||
doc.title = title
|
||||
await self.document_repository.update(doc)
|
||||
|
|
|
|||
|
|
@ -174,14 +174,18 @@ class TestResolveTitle:
|
|||
assert result == "Auto Extracted Title"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_structural_title_no_llm_returns_none(self, tmp_path):
|
||||
"""Returns None when no structural title and no LLM available."""
|
||||
async def test_llm_failure_returns_none(self, tmp_path, monkeypatch):
|
||||
"""LLM failure during ingestion returns None instead of raising."""
|
||||
doc = DoclingDocument(name="test")
|
||||
doc.add_text(label=DocItemLabel.PARAGRAPH, text="Just text")
|
||||
|
||||
client = self._make_client(tmp_path)
|
||||
|
||||
async def exploding_llm(self, content):
|
||||
raise RuntimeError("LLM is down")
|
||||
|
||||
monkeypatch.setattr(HaikuRAG, "_generate_title_with_llm", exploding_llm)
|
||||
result = await client._resolve_title(None, doc, "some content")
|
||||
# LLM call will fail without allow_model_requests, so we get None
|
||||
assert result is None
|
||||
|
||||
|
||||
|
|
@ -277,16 +281,15 @@ class TestGenerateTitle:
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_structural_title_no_llm(self, temp_db_path):
|
||||
"""generate_title returns None when no structural title and LLM unavailable."""
|
||||
"""generate_title raises when no structural title and LLM unavailable."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
doc = await client.create_document(
|
||||
"Just plain text without headings.",
|
||||
uri="test://gen-no-title",
|
||||
format="plain",
|
||||
)
|
||||
title = await client.generate_title(doc)
|
||||
# LLM blocked by ALLOW_MODEL_REQUESTS=False, so falls back to None
|
||||
assert title is None
|
||||
with pytest.raises(RuntimeError):
|
||||
await client.generate_title(doc)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bypasses_auto_title_config(self, temp_db_path):
|
||||
|
|
@ -357,3 +360,44 @@ class TestRebuildTitleOnly:
|
|||
processed_ids.append(doc_id)
|
||||
|
||||
assert len(processed_ids) == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_continues_on_per_document_failure(self, temp_db_path, monkeypatch):
|
||||
"""TITLE_ONLY mode continues when generate_title fails for a document."""
|
||||
from haiku.rag.client import RebuildMode
|
||||
|
||||
config = AppConfig(processing=ProcessingConfig(auto_title=True))
|
||||
async with HaikuRAG(temp_db_path, config=config, create=True) as client:
|
||||
doc1 = await client.create_document(
|
||||
"# First Heading\n\nContent.",
|
||||
uri="test://first",
|
||||
)
|
||||
doc2 = await client.create_document(
|
||||
"# Second Heading\n\nContent.",
|
||||
uri="test://second",
|
||||
)
|
||||
# Clear both titles
|
||||
doc1.title = None
|
||||
await client.document_repository.update(doc1)
|
||||
doc2.title = None
|
||||
await client.document_repository.update(doc2)
|
||||
|
||||
# Make generate_title fail for the first doc, succeed for the second
|
||||
original = HaikuRAG.generate_title
|
||||
call_count = 0
|
||||
|
||||
async def flaky_generate(self, document):
|
||||
nonlocal call_count
|
||||
call_count += 1
|
||||
if call_count == 1:
|
||||
raise RuntimeError("LLM failed")
|
||||
return await original(self, document)
|
||||
|
||||
monkeypatch.setattr(HaikuRAG, "generate_title", flaky_generate)
|
||||
|
||||
processed_ids = []
|
||||
async for doc_id in client.rebuild_database(mode=RebuildMode.TITLE_ONLY):
|
||||
processed_ids.append(doc_id)
|
||||
|
||||
# Only the second doc should have been processed
|
||||
assert len(processed_ids) == 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue