From 3b9e1f6e195dc94583b2e966dc620d3f2976fe07 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 18 Oct 2026 19:59:53 +0400 Subject: [PATCH] =?UTF-8?q?fix(normalizer):=20=D0=BA=D0=BE=D0=B4=20=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20=D0=BD=D0=B0=D0=B1=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=82=20=D0=BF=D0=B5=D1=80=D0=B2=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D1=87=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20json=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=B5?= =?UTF-8?q?=D1=81=D0=BB=D0=B8=20=D1=83=D1=81=D0=BF=D0=B5=D1=88=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D0=BD=D0=B5=D1=82=20(#46)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W --- api/src/normalizer/ocr/answer_set.py | 4 +++- api/tests/unit/normalizer/test_answer_set.py | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/api/src/normalizer/ocr/answer_set.py b/api/src/normalizer/ocr/answer_set.py index 9aa6c19..aae7ce1 100644 --- a/api/src/normalizer/ocr/answer_set.py +++ b/api/src/normalizer/ocr/answer_set.py @@ -61,19 +61,21 @@ def normalize_answer_set(raw: object, rules: Rules) -> AnswerSetResult: documents: list[StatementDocument] = [] warnings: list[StatementWarning] = [] first_error: FileError | None = None + succeeded = 0 for index, entry in enumerate(files): error = file_error(index, entry) if error is not None: warnings.append(error.to_warning(rules)) first_error = first_error or error continue + succeeded += 1 assert isinstance(entry, dict) # проверено file_error _normalize_file(entry, rules, documents, warnings) status = envelope_status([d.status for d in documents], warnings) if status is not EnvelopeStatus.ERROR: return AnswerSetResult(status, tuple(documents), tuple(warnings), None) - if first_error is not None: + if first_error is not None and not succeeded: # Р-33: код первого ошибочного, только когда все json ошибочны error_info = SetError(first_error.code, first_error.summary) else: error_info = SetError(ErrorCode.RECOGNITION_FAILED, NO_TABLES_MESSAGE) diff --git a/api/tests/unit/normalizer/test_answer_set.py b/api/tests/unit/normalizer/test_answer_set.py index f9adbc2..897156c 100644 --- a/api/tests/unit/normalizer/test_answer_set.py +++ b/api/tests/unit/normalizer/test_answer_set.py @@ -149,3 +149,11 @@ def test_ocr_column_dates_end_to_end(label: str, expected: date) -> None: doc = res.documents[0] assert [(c.period_kind, c.period_date) for c in doc.columns] == [(PeriodKind.ABSOLUTE, expected)] assert doc.header.report_date.value == date(2024, 12, 31) + + +@pytest.mark.parametrize("second", [response(), response(ocr_table("", [("Руководитель", "Иванов")]))]) +def test_one_failed_one_successful_without_documents_is_recognition_failed(second: dict[str, Any]) -> None: + res = normalize_answer_set(merged(("j.json", response(error=BAD)), ("j_ofr.json", second)), RULES) + assert res.status is EnvelopeStatus.ERROR and res.documents == () + assert (res.error.code, res.error.message) == (ErrorCode.RECOGNITION_FAILED, NO_TABLES_MESSAGE) + assert ("JSON_FAILED", "file:j.json") in [(w.code, w.locator) for w in res.file_warnings]