fix: harden /api/activity endpoint — prevent JSONDecodeError in CI#498
Conversation
…n failures - Use getattr for hardware_profile to handle missing state (test environments) - Wrap vram, cpu, npu, gpu, thermal, zram, network, process calls in try/except - Return empty defaults instead of crashing on partial failures - Fixes flaky test_activity_endpoint_returns_shape JSONDecodeError
📝 WalkthroughWalkthroughThe ChangesActivity endpoint defensive initialization and stats precomputation
🎯 2 (Simple) | ⏱️ ~10 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tinyagentos/routes/activity.py (1)
78-111: 💤 Low valueOptional: collapse the repeated try/except blocks into a helper.
The seven guarded calls share identical structure. A small
_safehelper would reduce duplication and make the fallback contract explicit, without changing behavior. (BroadExceptionis fine here—it won't swallowKeyboardInterrupt/SystemExit—so the Ruff BLE001 hints can be ignored for this defensive path.)♻️ Proposed helper-based refactor
def _safe(fn, default): try: return fn() except Exception: return default- try: - cpu_cores = get_cpu_per_core() - except Exception: - cpu_cores = [] - - try: - npu_cores = get_npu_per_core() - except Exception: - npu_cores = [] - - try: - gpu_load = get_gpu_load() - except Exception: - gpu_load = {} - - try: - thermal = get_thermal_zones() - except Exception: - thermal = [] - - try: - zram = get_zram_stats() - except Exception: - zram = {} - - try: - net_rates = get_network_rates() - except Exception: - net_rates = {} - - try: - procs = get_top_processes(limit=10) - except Exception: - procs = [] + cpu_cores = _safe(get_cpu_per_core, []) + npu_cores = _safe(get_npu_per_core, []) + gpu_load = _safe(get_gpu_load, {}) + thermal = _safe(get_thermal_zones, []) + zram = _safe(get_zram_stats, {}) + net_rates = _safe(get_network_rates, {}) + procs = _safe(lambda: get_top_processes(limit=10), [])🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tinyagentos/routes/activity.py` around lines 78 - 111, Repeated try/except blocks around sensor calls (get_cpu_per_core, get_npu_per_core, get_gpu_load, get_thermal_zones, get_zram_stats, get_network_rates, get_top_processes) should be collapsed into a small helper to reduce duplication and make fallbacks explicit; add a helper like _safe(fn, default) that calls fn() and returns default on Exception, then replace each try/except with cpu_cores = _safe(get_cpu_per_core, []), npu_cores = _safe(get_npu_per_core, []), gpu_load = _safe(get_gpu_load, {}), thermal = _safe(get_thermal_zones, []), zram = _safe(get_zram_stats, {}), net_rates = _safe(get_network_rates, {}), and procs = _safe(lambda: get_top_processes(limit=10), []).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tinyagentos/routes/activity.py`:
- Around line 78-111: Repeated try/except blocks around sensor calls
(get_cpu_per_core, get_npu_per_core, get_gpu_load, get_thermal_zones,
get_zram_stats, get_network_rates, get_top_processes) should be collapsed into a
small helper to reduce duplication and make fallbacks explicit; add a helper
like _safe(fn, default) that calls fn() and returns default on Exception, then
replace each try/except with cpu_cores = _safe(get_cpu_per_core, []), npu_cores
= _safe(get_npu_per_core, []), gpu_load = _safe(get_gpu_load, {}), thermal =
_safe(get_thermal_zones, []), zram = _safe(get_zram_stats, {}), net_rates =
_safe(get_network_rates, {}), and procs = _safe(lambda:
get_top_processes(limit=10), []).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 07bb2b91-c876-4925-9f62-bd32284cf632
📒 Files selected for processing (1)
tinyagentos/routes/activity.py
Summary
The
/api/activityendpoint returns 200 with empty body on CI runners, causingtest_activity_endpoint_returns_shapeto fail withJSONDecodeError: Expecting valueacross multiple PRs.Root cause
request.app.state.hardware_profileaccessed directly with dot notation, which raisesAttributeError(not caught) when the state attribute is missing in test environments. Additionally, sub-function calls (get_cpu_per_core,get_vram_usage,get_npu_per_core, etc.) can fail on headless CI runners.Fix
getattrfor safe hardware_profile accessget_npu_frequency()intentionally left unwrapped (it's already resilient internally)Testing
test_activity_endpoint_returns_shapeSummary by CodeRabbit
Release Notes