diff --git a/src/documents/management/commands/document_consumer.py b/src/documents/management/commands/document_consumer.py index e7ebe461c..e57569129 100644 --- a/src/documents/management/commands/document_consumer.py +++ b/src/documents/management/commands/document_consumer.py @@ -155,14 +155,9 @@ class FileStabilityTracker: logger.debug(f"File disappeared during stability check: {path}") continue - # File is stable - verify it's a regular file - try: - path.stat() - to_yield.append(path) - logger.info(f"File is stable: {path}") - except OSError as e: # pragma: no cover - logger.warning(f"Cannot access {path}: {e}") - to_remove.append(path) + # File is stable, we can return it + to_yield.append(path) + logger.info(f"File is stable: {path}") # Remove files that are no longer valid for path in to_remove: @@ -337,7 +332,7 @@ def _consume_file( if subdirs_as_tags: try: tag_ids = _tags_from_path(filepath, consumption_dir) - except Exception: # pragma: no cover + except Exception: logger.exception(f"Error creating tags from path for {filepath}") # Queue for consumption diff --git a/src/documents/tests/test_management_consumer.py b/src/documents/tests/test_management_consumer.py index 73b5464b0..46aa3d374 100644 --- a/src/documents/tests/test_management_consumer.py +++ b/src/documents/tests/test_management_consumer.py @@ -24,6 +24,7 @@ from typing import TYPE_CHECKING import pytest from django import db from django.core.management import CommandError +from django.db import DatabaseError from django.test import override_settings from watchfiles import Change @@ -248,6 +249,21 @@ class TestFileStabilityTracker: assert len(stable) == 0 assert tracker.pending_count == 0 + def test_get_stable_files_error_during_check( + self, + temp_file: Path, + mocker: MockerFixture, + ) -> None: + """Test a file which has become inaccessible is removed from tracking""" + + mocker.patch.object(Path, "stat", side_effect=PermissionError("denied")) + + tracker = FileStabilityTracker(stability_delay=0.1) + tracker.track(temp_file, Change.added) + stable = list(tracker.get_stable_files()) + assert len(stable) == 0 + assert tracker.pending_count == 0 + def test_multiple_files_tracking( self, stability_tracker: FileStabilityTracker, @@ -468,6 +484,32 @@ class TestConsumeFile: ) mock_consume_file_delay.delay.assert_not_called() + def test_consume_with_tags_error( + self, + consumption_dir: Path, + sample_pdf: Path, + mock_consume_file_delay: MagicMock, + mocker: MockerFixture, + ) -> None: + """Test _consume_file handles errors during tag creation""" + target = consumption_dir / "document.pdf" + shutil.copy(sample_pdf, target) + + mocker.patch( + "documents.management.commands.document_consumer._tags_from_path", + side_effect=DatabaseError("Something happened"), + ) + + _consume_file( + filepath=target, + consumption_dir=consumption_dir, + subdirs_as_tags=True, + ) + mock_consume_file_delay.delay.assert_called_once() + call_args = mock_consume_file_delay.delay.call_args + overrides = call_args[0][1] + assert overrides.tag_ids is None + @pytest.mark.django_db class TestTagsFromPath: