diff --git a/src/paperless/parsers/remote.py b/src/paperless/parsers/remote.py index 41989d834..963a7e9f0 100644 --- a/src/paperless/parsers/remote.py +++ b/src/paperless/parsers/remote.py @@ -21,6 +21,7 @@ from typing import Self from django.conf import settings +from documents.parsers import ParseError from paperless.version import __full_version_str__ if TYPE_CHECKING: @@ -366,8 +367,7 @@ class RemoteDocumentParser: """Send ``file`` to Azure AI Document Intelligence and return text. Downloads the searchable PDF output from Azure and stores it at - ``self._archive_path``. Returns the extracted text content, or - ``None`` on failure (the error is logged). + ``self._archive_path``. Parameters ---------- @@ -379,7 +379,14 @@ class RemoteDocumentParser: Returns ------- str | None - Extracted text, or None if the Azure call failed. + Extracted text. + + Raises + ------ + ParseError + If the Azure call fails for any reason. The error is logged + and re-raised so consumption fails loudly instead of silently + producing a document with no content. """ if TYPE_CHECKING: # Callers must have already validated config via engine_is_valid(): @@ -426,8 +433,7 @@ class RemoteDocumentParser: except Exception as e: logger.exception("Azure AI Vision parsing failed: %s", e) + raise ParseError(f"Azure AI Vision parsing failed: {e}") from e finally: client.close() - - return None diff --git a/src/paperless/tests/parsers/test_remote_parser.py b/src/paperless/tests/parsers/test_remote_parser.py index 99d3342be..931ab3ec5 100644 --- a/src/paperless/tests/parsers/test_remote_parser.py +++ b/src/paperless/tests/parsers/test_remote_parser.py @@ -20,6 +20,7 @@ from unittest.mock import Mock import pytest +from documents.parsers import ParseError from paperless.parsers import ParserContext from paperless.parsers import ParserProtocol from paperless.parsers.remote import RemoteDocumentParser @@ -342,15 +343,14 @@ class TestRemoteParserParse: class TestRemoteParserParseError: - def test_parse_returns_empty_on_azure_error( + def test_parse_raises_parse_error_on_azure_error( self, remote_parser: RemoteDocumentParser, simple_digital_pdf_file: Path, failing_azure_client: Mock, ) -> None: - remote_parser.parse(simple_digital_pdf_file, "application/pdf") - - assert remote_parser.get_text() == "" + with pytest.raises(ParseError, match="Azure AI Vision parsing failed"): + remote_parser.parse(simple_digital_pdf_file, "application/pdf") def test_parse_closes_client_on_error( self, @@ -358,7 +358,8 @@ class TestRemoteParserParseError: simple_digital_pdf_file: Path, failing_azure_client: Mock, ) -> None: - remote_parser.parse(simple_digital_pdf_file, "application/pdf") + with pytest.raises(ParseError): + remote_parser.parse(simple_digital_pdf_file, "application/pdf") failing_azure_client.close.assert_called_once() @@ -371,7 +372,8 @@ class TestRemoteParserParseError: ) -> None: mock_log = mocker.patch("paperless.parsers.remote.logger") - remote_parser.parse(simple_digital_pdf_file, "application/pdf") + with pytest.raises(ParseError): + remote_parser.parse(simple_digital_pdf_file, "application/pdf") mock_log.exception.assert_called_once() assert "Azure AI Vision parsing failed" in mock_log.exception.call_args[0][0]