Skip to content

Commit 99cd758

Browse files
committed
fix: resolve pr review comments
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
1 parent b90e0ad commit 99cd758

3 files changed

Lines changed: 42 additions & 15 deletions

File tree

services/apps/git_integration/src/crowdgit/database/crud.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from datetime import datetime, timezone
22

33
from loguru import logger
4-
from pydantic import TypeAdapter
4+
from pydantic import TypeAdapter, ValidationError
55
from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed
66

77
from crowdgit.enums import RepositoryPriority, RepositoryState
@@ -531,10 +531,14 @@ async def save_service_execution(service_execution: ServiceExecution) -> None:
531531
_AFFILIATION_SNAPSHOT_ADAPTER = TypeAdapter(list[AffiliationInfoItem])
532532

533533

534-
def parse_affiliation_snapshot(snapshot) -> list[AffiliationInfoItem]:
534+
def parse_affiliation_snapshot(snapshot) -> list[AffiliationInfoItem] | None:
535535
if isinstance(snapshot, dict) and "affiliations" in snapshot:
536536
snapshot = snapshot["affiliations"]
537-
return _AFFILIATION_SNAPSHOT_ADAPTER.validate_python(snapshot)
537+
try:
538+
return _AFFILIATION_SNAPSHOT_ADAPTER.validate_python(snapshot)
539+
except ValidationError as error:
540+
logger.warning(f"Invalid affiliation snapshot in registry, will re-parse: {error}")
541+
return None
538542

539543

540544
def dump_affiliation_snapshot(affiliations: list[AffiliationInfoItem]) -> list[dict]:

services/apps/git_integration/src/crowdgit/errors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class AffiliationFileNotFoundError(CrowdGitError):
115115
class AffiliationAnalysisError(CrowdGitError):
116116
error_message: str = "Could not parse the affiliation file"
117117
error_code: ErrorCode = ErrorCode.AFFILIATION_ANALYSIS_FAILED
118+
retain_file_hash: bool = False
118119

119120

120121
@dataclass

services/apps/git_integration/src/crowdgit/services/affiliation/affiliation_service.py

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,18 @@ async def pick_affiliation_file_with_ai(
290290
total_cost += result.cost
291291

292292
if result.output.file_name is not None:
293-
self.logger.info(f"Affiliation file: {result.output.file_name} (AI)")
294-
return result.output.file_name, total_cost
293+
picked_path = result.output.file_name
294+
if picked_path not in batch:
295+
self.logger.debug(
296+
f"AI picked path not in candidate batch, skipping: {picked_path!r}"
297+
)
298+
continue
299+
full_path = os.path.join(repo_path, picked_path)
300+
if not await aiofiles.os.path.isfile(full_path):
301+
self.logger.debug(f"AI picked path not on disk, skipping: {picked_path!r}")
302+
continue
303+
self.logger.info(f"Affiliation file: {picked_path} (AI)")
304+
return picked_path, total_cost
295305

296306
return None, total_cost
297307

@@ -471,13 +481,16 @@ async def parse_affiliations(
471481
affiliations = parse_result.output.affiliations
472482
if affiliations is not None:
473483
if not affiliations:
474-
raise AffiliationAnalysisError()
484+
return [], parse_result.cost
475485

476486
raw_count = len(affiliations)
477487
normalized = self.normalize_parsed_affiliations(affiliations)
478488

479489
if not normalized:
480-
raise AffiliationAnalysisError()
490+
raise AffiliationAnalysisError(
491+
retain_file_hash=True,
492+
error_message="Affiliation file had rows but none were usable",
493+
)
481494

482495
if len(normalized) < raw_count:
483496
self.logger.debug(
@@ -487,7 +500,7 @@ async def parse_affiliations(
487500
return normalized, parse_result.cost
488501

489502
if parse_result.output.error == "not_found":
490-
raise AffiliationAnalysisError()
503+
return [], parse_result.cost
491504

492505
raise AffiliationAnalysisError(
493506
error_message="Unexpected response while parsing the affiliation file",
@@ -533,7 +546,10 @@ async def process_chunk(chunk_index: int, chunk: str):
533546
normalized = self.normalize_parsed_affiliations(affiliations)
534547

535548
if not normalized:
536-
raise AffiliationAnalysisError()
549+
raise AffiliationAnalysisError(
550+
retain_file_hash=True,
551+
error_message="Affiliation file had rows but none were usable",
552+
)
537553

538554
if len(normalized) < raw_count:
539555
self.logger.debug(
@@ -542,7 +558,7 @@ async def process_chunk(chunk_index: int, chunk: str):
542558

543559
return normalized, total_cost
544560

545-
raise AffiliationAnalysisError()
561+
return [], total_cost
546562

547563
async def resolve_snapshot(
548564
self,
@@ -557,11 +573,13 @@ async def resolve_snapshot(
557573
"""
558574
stored_hash = registry.get("file_hash") if registry else None
559575
existing_snapshot = registry.get("snapshot") if registry else None
560-
needs_parse = (
561-
file_hash != stored_hash or existing_snapshot is None or not existing_snapshot
562-
)
576+
needs_parse = file_hash != stored_hash or existing_snapshot is None
563577

564578
if not needs_parse:
579+
if not existing_snapshot:
580+
self.logger.debug("Using cached empty snapshot, file unchanged")
581+
return [], 0.0
582+
565583
applyable = self.normalize_parsed_affiliations(existing_snapshot)
566584

567585
if applyable:
@@ -762,6 +780,7 @@ async def process_affiliations(
762780
error_message = None
763781
ai_cost = 0.0
764782
latest_file_path: str | None = None
783+
latest_file_hash: str | None = None
765784
registry = await get_repo_affiliation_registry(repository.id)
766785

767786
try:
@@ -792,6 +811,7 @@ async def process_affiliations(
792811
file_path_on_disk = os.path.join(batch_info.repo_path, latest_file_path)
793812
content = await self.read_text_file(file_path_on_disk)
794813
file_hash = self.compute_file_hash(content)
814+
latest_file_hash = file_hash
795815

796816
affiliations, parse_cost = await self.resolve_snapshot(
797817
registry,
@@ -833,9 +853,11 @@ async def process_affiliations(
833853
await upsert_repo_affiliation_registry(
834854
repository.id,
835855
file_path=latest_file_path,
836-
file_hash=None,
856+
file_hash=latest_file_hash if e.retain_file_hash else None,
837857
status=AffiliationRegistryStatus.ERROR.value,
838-
snapshot=registry.get("snapshot") if registry else None,
858+
snapshot=[]
859+
if e.retain_file_hash
860+
else (registry.get("snapshot") if registry else None),
839861
)
840862
self.logger.warning(error_message)
841863

0 commit comments

Comments
 (0)