Skip to content

Commit 88a1778

Browse files
committed
fix(importers): return ImportResult from handle_error
Implement handle_error() in all importers so errors return a concrete ImportResult (success=false, error_message set) instead of None, preventing NoneType.success crashes. Signed-off-by: phernandez <paul@basicmachines.co>
1 parent 4ce2198 commit 88a1778

4 files changed

Lines changed: 59 additions & 6 deletions

File tree

src/basic_memory/importers/chatgpt_importer.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@
1515
class ChatGPTImporter(Importer[ChatImportResult]):
1616
"""Service for importing ChatGPT conversations."""
1717

18+
def handle_error(
19+
self, message: str, error: Optional[Exception] = None
20+
) -> ChatImportResult:
21+
"""Return a failed ChatImportResult with an error message."""
22+
error_msg = f"{message}: {error}" if error else message
23+
return ChatImportResult(
24+
import_count={},
25+
success=False,
26+
error_message=error_msg,
27+
conversations=0,
28+
messages=0,
29+
)
30+
1831
async def import_data(
1932
self, source_data, destination_folder: str, **kwargs: Any
2033
) -> ChatImportResult:
@@ -67,7 +80,7 @@ async def import_data(
6780

6881
except Exception as e: # pragma: no cover
6982
logger.exception("Failed to import ChatGPT conversations")
70-
return self.handle_error("Failed to import ChatGPT conversations", e) # pyright: ignore [reportReturnType]
83+
return self.handle_error("Failed to import ChatGPT conversations", e)
7184

7285
def _format_chat_content(
7386
self, folder: str, conversation: Dict[str, Any]

src/basic_memory/importers/claude_conversations_importer.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import logging
44
from datetime import datetime
5-
from typing import Any, Dict, List
5+
from typing import Any, Dict, List, Optional
66

77
from basic_memory.markdown.schemas import EntityFrontmatter, EntityMarkdown
88
from basic_memory.importers.base import Importer
@@ -15,6 +15,19 @@
1515
class ClaudeConversationsImporter(Importer[ChatImportResult]):
1616
"""Service for importing Claude conversations."""
1717

18+
def handle_error(
19+
self, message: str, error: Optional[Exception] = None
20+
) -> ChatImportResult:
21+
"""Return a failed ChatImportResult with an error message."""
22+
error_msg = f"{message}: {error}" if error else message
23+
return ChatImportResult(
24+
import_count={},
25+
success=False,
26+
error_message=error_msg,
27+
conversations=0,
28+
messages=0,
29+
)
30+
1831
async def import_data(
1932
self, source_data, destination_folder: str, **kwargs: Any
2033
) -> ChatImportResult:
@@ -67,7 +80,7 @@ async def import_data(
6780

6881
except Exception as e: # pragma: no cover
6982
logger.exception("Failed to import Claude conversations")
70-
return self.handle_error("Failed to import Claude conversations", e) # pyright: ignore [reportReturnType]
83+
return self.handle_error("Failed to import Claude conversations", e)
7184

7285
def _format_chat_content(
7386
self,

src/basic_memory/importers/claude_projects_importer.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@
1414
class ClaudeProjectsImporter(Importer[ProjectImportResult]):
1515
"""Service for importing Claude projects."""
1616

17+
def handle_error(
18+
self, message: str, error: Optional[Exception] = None
19+
) -> ProjectImportResult:
20+
"""Return a failed ProjectImportResult with an error message."""
21+
error_msg = f"{message}: {error}" if error else message
22+
return ProjectImportResult(
23+
import_count={},
24+
success=False,
25+
error_message=error_msg,
26+
documents=0,
27+
prompts=0,
28+
)
29+
1730
async def import_data(
1831
self, source_data, destination_folder: str, **kwargs: Any
1932
) -> ProjectImportResult:
@@ -73,7 +86,7 @@ async def import_data(
7386

7487
except Exception as e: # pragma: no cover
7588
logger.exception("Failed to import Claude projects")
76-
return self.handle_error("Failed to import Claude projects", e) # pyright: ignore [reportReturnType]
89+
return self.handle_error("Failed to import Claude projects", e)
7790

7891
def _format_project_markdown(
7992
self, project: Dict[str, Any], doc: Dict[str, Any], destination_folder: str = ""

src/basic_memory/importers/memory_json_importer.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Memory JSON import service for Basic Memory."""
22

33
import logging
4-
from typing import Any, Dict, List
4+
from typing import Any, Dict, List, Optional
55

66
from basic_memory.markdown.schemas import EntityFrontmatter, EntityMarkdown, Observation, Relation
77
from basic_memory.importers.base import Importer
@@ -13,6 +13,20 @@
1313
class MemoryJsonImporter(Importer[EntityImportResult]):
1414
"""Service for importing memory.json format data."""
1515

16+
def handle_error(
17+
self, message: str, error: Optional[Exception] = None
18+
) -> EntityImportResult:
19+
"""Return a failed EntityImportResult with an error message."""
20+
error_msg = f"{message}: {error}" if error else message
21+
return EntityImportResult(
22+
import_count={},
23+
success=False,
24+
error_message=error_msg,
25+
entities=0,
26+
relations=0,
27+
skipped_entities=0,
28+
)
29+
1630
async def import_data(
1731
self, source_data, destination_folder: str = "", **kwargs: Any
1832
) -> EntityImportResult:
@@ -113,4 +127,4 @@ async def import_data(
113127

114128
except Exception as e: # pragma: no cover
115129
logger.exception("Failed to import memory.json")
116-
return self.handle_error("Failed to import memory.json", e) # pyright: ignore [reportReturnType]
130+
return self.handle_error("Failed to import memory.json", e)

0 commit comments

Comments
 (0)