From b7eb7cc7c0526364d4e6bb639174ff6baef76e19 Mon Sep 17 00:00:00 2001 From: Ruanyuxi1337 Date: Mon, 6 Jul 2026 22:27:53 +0800 Subject: [PATCH] Fix uncaught pydantic ValidationError crash on malformed LLM response --- src/skillspector/llm_analyzer_base.py | 39 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/skillspector/llm_analyzer_base.py b/src/skillspector/llm_analyzer_base.py index c5ab9dce..beead116 100644 --- a/src/skillspector/llm_analyzer_base.py +++ b/src/skillspector/llm_analyzer_base.py @@ -428,12 +428,39 @@ async def _process(batch: Batch) -> tuple[Batch, list]: estimate_tokens(prompt), len(batch.findings), ) - if self._structured_llm: - response = await self._structured_llm.ainvoke(prompt) - else: - response = _message_text(await self._llm.ainvoke(prompt)) - logger.debug("LLM response for %s", batch.file_label) - return (batch, self.parse_response(response, batch)) + try: + if self._structured_llm: + response = await self._structured_llm.ainvoke(prompt) + else: + response = _message_text(await self._llm.ainvoke(prompt)) + logger.debug("LLM response for %s", batch.file_label) + parsed = self.parse_response(response, batch) + return (batch, parsed) + except NotImplementedError as exc: + # Do not retry on configuration / code errors + raise exc + except Exception as exc: + logger.warning( + "LLM call/parse failed for %s: %s (attempting retry)", + batch.file_label, + exc, + ) + # Retry once before throwing + try: + if self._structured_llm: + response = await self._structured_llm.ainvoke(prompt) + else: + response = _message_text(await self._llm.ainvoke(prompt)) + logger.debug("LLM response for %s on retry", batch.file_label) + parsed = self.parse_response(response, batch) + return (batch, parsed) + except Exception as retry_exc: + logger.warning( + "LLM call/parse retry failed for %s: %s", + batch.file_label, + retry_exc, + ) + raise retry_exc results = await asyncio.gather(*[_process(b) for b in batches], return_exceptions=True) successful: list[tuple[Batch, list]] = []