Files
Plugin_SN_Basis/assets/plan-qgis340ExitCrashFix.prompt.md
T

4.0 KiB
Raw Blame History

Plan: QGIS 3.40 Exit-Crash absichern

Der wahrscheinlichste Auslöser ist fehlendes Signal-Cleanup beim Plugin-Unload: globale Projekt-Listener und PrintTab-Listener bleiben aktiv, während QgsProject beim QGIS-Exit bereits zerstört wird. Die empfohlene Lösung ist ein minimaler, versionsneutraler Cleanup-Pfad (disconnect + defensive Guards), ohne Fachlogik zu ändern.

Steps

  1. Teardown-Funktion für globale Verfahrensgebiet-Listener ergänzen, inkl. idempotentem Disconnect und Rücksetzen des Installationsflags.

    • Datei: sn_basis/functions/verfahrensgebiet_manager.py (nach setup_verfahrensgebiet_listener, ca. Zeile 132)
    • Neue Funktion teardown_verfahrensgebiet_listener() disconnect alle 5 QgsProject-Signale (layersAdded, layerRemoved, readProject, newProjectCreated, cleared) und setzt _listener_installed = False zurück.
    • RuntimeError abfangen (Projekt wird gerade zerstört → normal).
  2. Teardown in Unload-Pfad vor UI-Abbau aufrufen. (depends on step 1)

    • Datei: sn_basis/main.py (in BasisPlugin.unload, ca. Zeile 52)
    • Import und Aufruf von teardown_verfahrensgebiet_listener() als erste Zeile in unload(), bevor self.ui.remove_all() ausgeführt wird.
  3. PrintTab um kleinen Projekt-Signal-Cleanup ergänzen, symmetrisch zu bestehendem Theme-Cleanup. (parallel mit step 1)

    • Datei: sn_basis/ui/tabs/print_tab.py
    • Neue Methode cleanup() nach _disconnect_theme_collection_signals (ca. Zeile 485).
    • Disconnectet QgsProject-Signale (readProject, newProjectCreated, cleared) von self._on_project_changed (analog zu bestehendem Theme-Disconnect-Muster).
    • Ruft danach self._disconnect_theme_collection_signals() auf.
  4. BaseDockWidget.closeEvent so erweitern, dass Tab-Cleanup-Hooks vor Schließen aufgerufen werden. (depends on step 3)

    • Datei: sn_basis/ui/base_dockwidget.py (in closeEvent, ca. Zeile 97)
    • Vor dem bestehenden self.action.setChecked(False) Block: über alle Tabs iterieren, auf cleanup-Attribut prüfen, aufrufen; Exception abfangen.
  5. Optional nur bei Restinstabilität: defensive Guards bei Projektzugriffen in kritischen Handlern ergänzen.

    • Datei: sn_basis/functions/variable_wrapper.py (in get_variable/set_variable, ca. Zeile 60 und 89)
    • Datei: sn_basis/functions/verfahrensgebiet_manager.py (in _on_layer_removed, ca. Zeile 114)
    • QgsProject.instance() auf None/RuntimeError prüfen und bei Zerstörung früh zurückkehren.

Relevant files

  • sn_basis/functions/verfahrensgebiet_manager.py — Listener-Setup/Teardown, Handler-Guards
  • sn_basis/main.py — Unload-Reihenfolge
  • sn_basis/ui/tabs/print_tab.py — Projekt-Signal-Cleanup
  • sn_basis/ui/base_dockwidget.py — zentraler Cleanup-Hook
  • sn_basis/ui/dockmanager.py — asynchrones deleteLater als Lifecycle-Kontext
  • sn_basis/functions/variable_wrapper.py — optional defensive Guards

Decisions

  • Include: minimaler Lifecycle-Fix über disconnect + Guards.
  • Exclude: Refactoring der gesamten Signal-Architektur, größere UI-Umbauten, versionsspezifische If-Branches.
  • Begründung: geringstes Risiko für Regressionen bei maximaler Wirkung gegen Shutdown-Crashs.
  • Keine Änderung an Business-Logik, keine Änderung an Variablennamen, keine QGIS-versionsspezifischen Sonderpfade — rein sichere Disconnect/Guard-Muster.

Verification

  1. Plugin laden, Dock öffnen/schließen, Projekt neu laden, Layer „Verfahrensgebiet" add/remove, dann QGIS 3.40.7 beenden → kein Access Violation.
  2. Dasselbe unter QGIS 4 → unverändertes Verhalten, keine Regression.
  3. Mehrfacher Plugin-Reload in einer Sitzung → keine doppelten Signal-Reaktionen, keine Exceptions beim Unload.
  4. Optionaler Stresstest: Unit-Test für idempotentes Teardown (mehrfaches unload ohne Exception).

Further considerations

  • Step 5 (defensive Guards in variable_wrapper) nur umsetzen, wenn nach Steps 14 noch reproduzierbare Exit-Crashs auftreten.
  • Ein kleiner Unit-Test für idempotentes Teardown (mehrfaches unload() ohne Exception) wäre empfehlenswert, falls die Testsuite erweitert wird.