mirror of
https://github.com/Horizontal42/Sort_YM.git
synced 2026-11-11 02:12:00 +03:00
catch schema-incomplete ollama responses instead of crashing the batch
This commit is contained in:
parent
12145cc82a
commit
93127e37d8
2 changed files with 21 additions and 4 deletions
|
|
@ -252,16 +252,19 @@ def analyze_tracks(
|
|||
}
|
||||
try:
|
||||
data = call(settings, prompt)
|
||||
entry = {**data, **stamp, "key_line_verified": verify_key_line(data["key_line"], text)}
|
||||
# Широкий except намеренно: трёхчасовой прогон не должен падать целиком из-за
|
||||
# одного зависшего/битого ответа локальной модели. KeyboardInterrupt и SystemExit
|
||||
# наследуются от BaseException и сюда не попадают - Ctrl+C прерывает прогон.
|
||||
# одного зависшего/битого ответа локальной модели - в том числе синтаксически
|
||||
# валидного JSON без обязательного поля (KeyError здесь же, не только в call()).
|
||||
# KeyboardInterrupt и SystemExit наследуются от BaseException и сюда не попадают -
|
||||
# Ctrl+C прерывает прогон.
|
||||
except Exception as e:
|
||||
cache[tid] = {**stamp, "error": f"{type(e).__name__}: {e}"}
|
||||
failed += 1
|
||||
print(f" [{i}/{len(pending)}] {info['title']} - ошибка: {type(e).__name__}")
|
||||
else:
|
||||
cache[tid] = {**data, **stamp, "key_line_verified": verify_key_line(data["key_line"], text)}
|
||||
print(f" [{i}/{len(pending)}] {info['title']} - {', '.join(data['mood'])}")
|
||||
cache[tid] = entry
|
||||
print(f" [{i}/{len(pending)}] {info['title']} - {', '.join(entry.get('mood', []))}")
|
||||
_atomic_write_json(cache_file, cache)
|
||||
|
||||
if failed:
|
||||
|
|
|
|||
|
|
@ -246,6 +246,20 @@ def test_analyze_records_error_marker_and_continues(tmp_path: Path):
|
|||
assert result["200"]["summary"] == "Герой бродит по городу.", "таймаут одного трека не роняет батч"
|
||||
|
||||
|
||||
def test_analyze_records_error_marker_for_schema_incomplete_response(tmp_path: Path):
|
||||
# Ollama иногда возвращает синтаксически валидный JSON без обязательного поля -
|
||||
# это не исключение внутри call(), падает на доступе к data[...] после успешного возврата.
|
||||
def call(settings, prompt):
|
||||
if "Тоска" in prompt:
|
||||
return {k: v for k, v in GOOD_RESPONSE.items() if k != "key_line"}
|
||||
return dict(GOOD_RESPONSE)
|
||||
|
||||
result = analyze.analyze_tracks(TRACKS, LYRICS, tmp_path, _settings(), call=call)
|
||||
|
||||
assert "KeyError" in result["100"]["error"]
|
||||
assert result["200"]["summary"] == "Герой бродит по городу.", "битый ответ одного трека не роняет батч"
|
||||
|
||||
|
||||
def test_analyze_retries_error_entries_on_next_run(tmp_path: Path):
|
||||
def failing(settings, prompt):
|
||||
raise TimeoutError("модель зависла")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue