Skip to content

Commit 6d9c2ea

Browse files
committed
Clean up client discovery error handling
Simplify and improve error handling in client discovery: 1. Remove systemd section from development.md (belongs in deployment docs) 2. Remove special case for python3-smbus - handle all errors uniformly 3. Simplify error handling logic: - Inner try/except: catches errors importing *_client.py submodule - Outer try/except: catches errors importing package itself - Both use shared _format_error_message() helper for consistency Error messages now consistently show first line of actual error, providing useful context without cluttering the output.
1 parent 49241f9 commit 6d9c2ea

File tree

2 files changed

+25
-50
lines changed

2 files changed

+25
-50
lines changed

docs/development.md

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -181,28 +181,6 @@ To see all built-in clients:
181181
pipenv run pi-pianoteq --list-clients
182182
```
183183

184-
### Systemd Service
185-
186-
To use a specific client with the systemd service, edit the service file:
187-
188-
```bash
189-
sudo systemctl edit pi-pianoteq.service --full
190-
```
191-
192-
Update the `ExecStart` line to specify the client:
193-
194-
```ini
195-
[Service]
196-
ExecStart=/home/pi/pi-pianoteq-venv/bin/pi-pianoteq --client cli
197-
```
198-
199-
Then reload and restart:
200-
201-
```bash
202-
sudo systemctl daemon-reload
203-
sudo systemctl restart pi-pianoteq.service
204-
```
205-
206184
## What deploy.sh Does
207185

208186
The deployment script:

src/pi_pianoteq/client/discovery.py

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@
1212
from pi_pianoteq.client.client import Client
1313

1414

15+
def _format_error_message(error_msg: str) -> str:
16+
"""
17+
Format import error message for display.
18+
19+
Args:
20+
error_msg: Raw error message from ImportError
21+
22+
Returns:
23+
User-friendly formatted error message
24+
"""
25+
if 'No module named' in error_msg:
26+
# Extract just the missing module name
27+
missing = error_msg.split("'")[1] if "'" in error_msg else error_msg
28+
return f"missing dependency: {missing}"
29+
else:
30+
# Keep first line of error only, truncate if too long
31+
first_line = error_msg.split('\n')[0]
32+
return first_line[:60] if len(first_line) > 60 else first_line
33+
34+
1535
def discover_builtin_clients() -> Dict[str, Type[Client]]:
1636
"""
1737
Scan pi_pianoteq.client.* for Client subclasses.
@@ -44,9 +64,6 @@ def discover_builtin_clients_with_errors() -> Tuple[Dict[str, Type[Client]], Dic
4464
# Skip base classes and this module
4565
continue
4666

47-
client_found = False
48-
import_error = None
49-
5067
try:
5168
# Import the module
5269
full_module_name = f'pi_pianoteq.client.{modname}'
@@ -60,8 +77,9 @@ def discover_builtin_clients_with_errors() -> Tuple[Dict[str, Type[Client]], Dic
6077
submodule = importlib.import_module(submodule_name)
6178
module = submodule
6279
except ImportError as e:
63-
# Track this error for potential unavailable listing
64-
import_error = e
80+
# If the submodule can't be imported, mark as unavailable
81+
unavailable[modname] = _format_error_message(str(e))
82+
continue
6583

6684
# Find Client subclasses in the module
6785
for name, obj in inspect.getmembers(module, inspect.isclass):
@@ -70,32 +88,11 @@ def discover_builtin_clients_with_errors() -> Tuple[Dict[str, Type[Client]], Dic
7088
obj.__module__.startswith('pi_pianoteq.client')):
7189
# Use the module/package name as the client name
7290
available[modname] = obj
73-
client_found = True
7491
break # Only take the first Client subclass from each module
7592

76-
# If we didn't find a client but had an import error, mark as unavailable
77-
if not client_found and import_error:
78-
error_msg = str(import_error)
79-
if 'No module named' in error_msg:
80-
missing = error_msg.split("'")[1] if "'" in error_msg else error_msg
81-
unavailable[modname] = f"missing dependency: {missing}"
82-
elif 'python3-smbus' in error_msg:
83-
unavailable[modname] = "missing dependency: python3-smbus"
84-
else:
85-
# Keep first line of error only
86-
first_line = error_msg.split('\n')[0]
87-
unavailable[modname] = first_line[:60] # Truncate if too long
88-
8993
except ImportError as e:
90-
# Track modules that can't be imported (e.g., missing dependencies)
91-
# Extract a user-friendly error message
92-
error_msg = str(e)
93-
if 'No module named' in error_msg:
94-
# Extract just the missing module name
95-
missing = error_msg.split("'")[1] if "'" in error_msg else error_msg
96-
unavailable[modname] = f"missing dependency: {missing}"
97-
else:
98-
unavailable[modname] = f"import error: {error_msg}"
94+
# Package itself can't be imported
95+
unavailable[modname] = _format_error_message(str(e))
9996

10097
return available, unavailable
10198

0 commit comments

Comments
 (0)