fix: Handle EntityCreationError as conflict#541
Conversation
Signed-off-by: phernandez <paul@basicmachines.co>
|
Claude finished @phernandez's task in 2m 26s —— View job PR Review CompleteReviewing PR #541: Handle EntityCreationError as conflict Todo List
SummaryThis PR improves error handling for entity creation conflicts by:
Review Against Team Checklist✅ Code Quality & Standards
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba29d52036
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
src/basic_memory/api/app.py
Outdated
| @app.exception_handler(EntityCreationError) | ||
| async def entity_creation_error_handler(request, exc): # pragma: no cover | ||
| """Handle entity creation conflicts (e.g., file already exists). | ||
|
|
||
| This is expected behavior when users try to create notes that exist, | ||
| so log at INFO level instead of ERROR. | ||
| """ | ||
| logger.info( | ||
| "Entity already exists", | ||
| url=str(request.url), | ||
| method=request.method, | ||
| path=request.url.path, | ||
| error=str(exc), | ||
| ) | ||
| return await http_exception_handler( | ||
| request, | ||
| HTTPException( | ||
| status_code=409, | ||
| detail="Note already exists. Use edit_note to modify it, or delete it first.", | ||
| ), |
There was a problem hiding this comment.
Return 409 only for actual conflicts
This handler treats every EntityCreationError as an “already exists” conflict, but EntityCreationError is also raised for non-conflict failures (e.g., create_entity_from_markdown wraps any upsert_entity exception into EntityCreationError). In those cases clients will now receive a 409 with a misleading “Note already exists” message instead of a 500, and logs will be INFO, which can mask real storage or database failures. Consider narrowing this to only the file-exists case (e.g., a specific exception subtype) or preserving the original error status for unexpected creation failures.
Useful? React with 👍 / 👎.
Signed-off-by: phernandez <paul@basicmachines.co>
|
Claude finished @phernandez's task in 2m 12s —— View job Reviewing PR #541: Handle EntityCreationError as conflict Todo List
SummaryThis PR improves error handling for entity creation conflicts: Commit 1 (ba29d52):
Commit 2 (718ba6c):
Review Against Team Checklist✅ Code Quality & Standards
✅ Testing & Documentation
✅ Basic Memory Architecture
✅ Security & Performance
✅ Compatibility
Critical Issue: Codex Concern is Valid
|
Signed-off-by: phernandez <paul@basicmachines.co>
|
Claude finished @phernandez's task in 1m 50s —— View job Reviewing PR #541: Handle EntityCreationError as conflict Todo List
SummaryThis PR successfully addresses entity creation conflicts with a three-commit evolution: Commit 1 (ba29d52): Initial implementation
Commit 2 (718ba6c): Addressed initial review feedback
Commit 3 (8aecae3): Addressed Codex critical concern ✅
Review Against Team Checklist✅ Code Quality & Standards
✅ Testing & Documentation
✅ Basic Memory Architecture
✅ Security & Performance
✅ Compatibility
Critical Issue Resolution ✅The Codex concern about treating all EntityCreationError as conflicts has been fully resolved in commit 8aecae3. What Was FixedBefore (commits 1-2): @app.exception_handler(EntityCreationError) # ❌ Too broad
async def entity_creation_error_handler(request: Request, exc: EntityCreationError):
# All EntityCreationError → 409 (wrong for DB failures!)After (commit 3): @app.exception_handler(EntityAlreadyExistsError) # ✅ Specific
async def entity_already_exists_error_handler(request: Request, exc: EntityAlreadyExistsError):
# Only file-exists conflicts → 409Implementation Details
Code Quality NotesExcellent Patterns ✅
Minor Observations
Test Coverage AnalysisIntegration Test (test_knowledge_router.py:185-210)async def test_create_entity_conflict_returns_409(client: AsyncClient, v2_project_url):
"""Test creating a duplicate entity returns 409 Conflict."""What it tests:
Coverage: This test covers the Test Formatting Changes (test_search_service.py)Lines 348-350, 369-371, 401-403: Moved assertion messages to same line for better readability. These changes are covered by existing boolean search tests. Final Verdict✅ READY TO MERGEAll concerns from previous reviews have been addressed:
Positive Highlights
No Blockers RemainingAll checklist items pass. The implementation follows Basic Memory's conventions, maintains 100% test coverage, and properly handles both conflict and failure scenarios with appropriate status codes and logging levels. |
Summary\n- log EntityCreationError at INFO and return 409 conflict\n- include friendly detail message for existing notes\n- include formatting fix in tests\n\n## Testing\n- not run (not requested)