Skip to content

Commit d986c4d

Browse files
committed
fix(core): preserve file service read contract
Signed-off-by: phernandez <paul@basicmachines.co>
1 parent 49a40be commit d986c4d

2 files changed

Lines changed: 10 additions & 6 deletions

File tree

src/basic_memory/services/file_service.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,9 @@ async def read_file_bytes(self, path: FilePath) -> bytes:
308308
)
309309
return content
310310

311-
except FileNotFoundError:
312-
# Preserve FileNotFoundError so callers (e.g. sync) can treat it as deletion.
313-
logger.warning("File not found", operation="read_file_bytes", path=str(full_path))
314-
raise
315311
except Exception as e:
316312
logger.exception("File read error", path=str(full_path), error=str(e))
317-
raise FileOperationError(f"Failed to read file: {e}")
313+
raise FileOperationError(f"Failed to read file: {e}") from e
318314

319315
async def read_file(self, path: FilePath) -> Tuple[str, str]:
320316
"""Read file and compute checksum using true async I/O.

src/basic_memory/sync/sync_service.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from basic_memory.repository.search_repository import create_search_repository
4040
from basic_memory.services import EntityService, FileService
4141
from basic_memory.repository.semantic_errors import SemanticDependenciesMissingError
42-
from basic_memory.services.exceptions import SyncFatalError
42+
from basic_memory.services.exceptions import FileOperationError, SyncFatalError
4343
from basic_memory.services.link_resolver import LinkResolver
4444
from basic_memory.services.search_service import SearchService
4545

@@ -628,6 +628,14 @@ async def load(path: str) -> None:
628628
)
629629
except FileNotFoundError:
630630
await self.handle_delete(path)
631+
except FileOperationError as exc:
632+
# Trigger: FileService wraps binary read failures in FileOperationError.
633+
# Why: the service contract should stay consistent for direct callers.
634+
# Outcome: sync still treats wrapped missing-file reads as deletions.
635+
if isinstance(exc.__cause__, FileNotFoundError):
636+
await self.handle_delete(path)
637+
else:
638+
errors[path] = str(exc)
631639
except Exception as exc:
632640
errors[path] = str(exc)
633641

0 commit comments

Comments
 (0)