Skip to content

Commit d50d4ad

Browse files
Lukas Geigerclaude
andcommitted
fix: TreePanel._on_item_expanded – OSError statt nur PermissionError abfangen
Nur PermissionError wurde abgefangen; andere OSError-Varianten (z.B. WinError 21 "Gerät nicht bereit" bei ausgeworfenen Laufwerken, Netzwerkpfade die wegfallen) propagierten unkontrolliert. Da PermissionError eine Subklasse von OSError ist, reicht ein einziger `except OSError`-Block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent fcad364 commit d50d4ad

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

src/gui/sidebar/sidebar_main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def _on_item_expanded(self, item: QTreeWidgetItem):
110110
child.setIcon(0, self._icon_provider.icon(QFileInfo(full_path)))
111111
child.setChildIndicatorPolicy(QTreeWidgetItem.ChildIndicatorPolicy.ShowIndicator)
112112
item.addChild(child)
113-
except PermissionError:
113+
except OSError:
114114
pass
115115

116116

tests/test_sidebar_oserror.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""
2+
Bugfix-Test: sidebar_main.py TreePanel._on_item_expanded() –
3+
Nur PermissionError wurde abgefangen; andere OSError-Varianten
4+
(z.B. [WinError 21] Gerät nicht bereit) propagierten unkontrolliert.
5+
Behoben durch Fangen von OSError (Oberklasse, schließt PermissionError ein).
6+
"""
7+
from __future__ import annotations
8+
9+
import os
10+
import sys
11+
from pathlib import Path
12+
from unittest.mock import patch
13+
14+
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
15+
16+
SRC_DIR = Path(__file__).resolve().parents[1] / "src"
17+
if str(SRC_DIR) not in sys.path:
18+
sys.path.insert(0, str(SRC_DIR))
19+
20+
from PySide6.QtWidgets import QApplication
21+
_app = QApplication.instance() or QApplication([])
22+
23+
from PySide6.QtCore import Qt
24+
from PySide6.QtWidgets import QTreeWidgetItem
25+
26+
from gui.sidebar.sidebar_main import TreePanel
27+
28+
29+
class TestTreePanelOsErrorFix:
30+
"""_on_item_expanded muss alle OSError-Varianten abfangen."""
31+
32+
def _make_tree(self) -> TreePanel:
33+
return TreePanel()
34+
35+
def test_permission_error_handled(self):
36+
"""PermissionError (OSError-Subklasse) darf keinen Crash verursachen."""
37+
panel = self._make_tree()
38+
39+
item = QTreeWidgetItem(["/fake/path"])
40+
item.setData(0, Qt.ItemDataRole.UserRole, "/fake/path")
41+
panel.tree.addTopLevelItem(item)
42+
43+
with patch("os.listdir", side_effect=PermissionError("Zugriff verweigert")):
44+
panel._on_item_expanded(item) # darf nicht crashen
45+
46+
def test_generic_oserror_handled(self):
47+
"""Generische OSError (z.B. Gerät nicht bereit) darf keinen Crash verursachen."""
48+
panel = self._make_tree()
49+
50+
item = QTreeWidgetItem(["/fake/drive"])
51+
item.setData(0, Qt.ItemDataRole.UserRole, "/fake/drive")
52+
panel.tree.addTopLevelItem(item)
53+
54+
with patch("os.listdir", side_effect=OSError(21, "Das Gerät ist nicht bereit")):
55+
panel._on_item_expanded(item) # darf nicht crashen

0 commit comments

Comments
 (0)