fix(graphrag): crash on project rename/path change (DF-009)
session_events.py::_on_projects_changed (runs on every project create/rename/delete) called self.structure._refresh_project_combo() — but that method only ever existed on GraphRenderer, not on StructureGraphView itself (self.structure). Renaming a project or changing its working-directory path raised AttributeError and crashed the app. Add StructureGraphView.refresh_project_list(), matching the existing schedule_rescan/set_project/prewarm forwarding pattern, and call that instead. Add a regression test (test_refresh_project_list_forwards_to_renderer). Logged as DF-009 in Task Tracking Template.xlsx — root cause, fix and regression test recorded (row was empty in this local copy despite being reported as already logged there). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -219,6 +219,12 @@ class StructureGraphView(QWidget):
|
||||
"""Dựng sẵn khung đồ thị trước khi người dùng bấm vào, để lần mở đầu không giật."""
|
||||
self.renderer.prewarm()
|
||||
|
||||
def refresh_project_list(self) -> None:
|
||||
"""Project khác vừa được tạo/sửa/xoá/đổi tên — làm mới danh sách trong
|
||||
bộ chọn project của renderer (bộ chọn KHÔNG tự nạp lại khi project
|
||||
thay đổi ở màn khác, chỉ khi ``set_project`` được gọi)."""
|
||||
self.renderer._refresh_project_combo()
|
||||
|
||||
def hideEvent(self, e): # noqa: N802
|
||||
# Leaving the GraphRAG tab → drop the temporary extracted info.
|
||||
"""Rời màn GraphRAG thì xoá phần trích xuất tạm của khung hỏi-đáp."""
|
||||
|
||||
@@ -106,4 +106,4 @@ class SessionEventsMixin:
|
||||
"""Project được tạo/sửa/xoá: gom nhóm lại cột lịch sử và cập nhật nhãn thư mục."""
|
||||
self.sidebar.refresh() # History regroups by project
|
||||
self.cowork._apply_output_folder_label() # project may have been renamed
|
||||
self.structure._refresh_project_combo() # GraphRAG's project lock list follows too
|
||||
self.structure.refresh_project_list() # GraphRAG's project lock list follows too
|
||||
|
||||
@@ -55,6 +55,25 @@ def test_structure_graph_view_builds(ctx):
|
||||
assert view.qa is not None
|
||||
|
||||
|
||||
def test_refresh_project_list_forwards_to_renderer(ctx):
|
||||
"""Crash bug: ``presentation/shell/session_events.py::_on_projects_changed``
|
||||
called ``self.structure._refresh_project_combo()`` — a method that only
|
||||
ever existed on ``GraphRenderer``, not on ``StructureGraphView`` itself —
|
||||
so creating/renaming/deleting a project (anywhere in the app) raised
|
||||
``AttributeError`` and crashed. ``refresh_project_list()`` is the public
|
||||
forwarding method callers must use instead (matching ``schedule_rescan``/
|
||||
``set_project``/``prewarm``'s existing forwarding pattern)."""
|
||||
from cowork_local.presentation.graph.structure_graph_view import StructureGraphView
|
||||
|
||||
view = StructureGraphView(ctx)
|
||||
assert not hasattr(view, "_refresh_project_combo")
|
||||
|
||||
combo = view.renderer.project_combo
|
||||
before = combo.count()
|
||||
view.refresh_project_list() # must not raise
|
||||
assert combo.count() == before # re-populated from the same project list, same size
|
||||
|
||||
|
||||
def test_render_populates_the_scene_and_emits_graph_rendered(ctx, tmp_path):
|
||||
from cowork_local.presentation.graph.graph_renderer import GraphRenderer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user