Fix signal handler cleanup bug when startup fails early #54

Merged
JackFrostbyte merged 2 commits from fix/issue-45-signal-handler-startup-failure into develop 2026-05-13 01:12:56 -04:00
Collaborator

Closes #45.

Summary

Initializes previous_sigterm_handler = None in run_combined_runtime before the try block, so the finally cleanup is safe when startup fails before the SIGTERM handler is registered.

Adds a regression test that simulates early startup failure (mapping validation error) and asserts the function returns the correct exit code (2) without raising UnboundLocalError.

Root cause

src/rgb_aura/runtime.py had previous_sigterm_handler assigned only inside the try block, after _connect_and_validate() succeeded. The finally block referenced it unconditionally. If any of the following raised before the assignment:

  • OpenRGB connection refused / unreachable
  • _connect_and_validate() device mapping validation error
  • _build_runtime_zones() validation error

...then the finally block raised UnboundLocalError: cannot access local variable 'previous_sigterm_handler', which masked the original startup exception and made troubleshooting harder.

Fix

One-line addition: initialize the variable to None before the try. The existing if previous_sigterm_handler is not None: guard in the finally now correctly skips the SIGTERM restore when the handler was never registered.

Regression test

tests/test_runtime.py::test_run_combined_runtime_returns_mapping_error_when_validation_fails

  • Monkeypatches _connect_and_validate to raise DeviceMappingError.
  • Calls run_combined_runtime with otherwise valid runtime args.
  • Asserts the function returns exit code 2 (mapping error), not raises.
  • Asserts the SIGTERM handler is left untouched (no leaked global state).

Without the fix, this test would fail with UnboundLocalError propagating from the finally block. With the fix, it passes cleanly.

Verification before commit

  • python -m pytest tests/ — 1 passed.
  • ruff check src/ tests/ — all checks passed.
  • ruff format --check src/ tests/ — 23 files already formatted.
  • python -m rgb_aura.main --dry-run --dry-run-events 3 — clean run, all 14 animations registered, scheduler preview produces events normally.

Branch workflow

  • Base branch: develop
  • Work branch: fix/issue-45-signal-handler-startup-failure
  • Pull request target: develop
  • Not merged directly into main.
Closes #45. ## Summary Initializes `previous_sigterm_handler = None` in `run_combined_runtime` before the `try` block, so the `finally` cleanup is safe when startup fails before the SIGTERM handler is registered. Adds a regression test that simulates early startup failure (mapping validation error) and asserts the function returns the correct exit code (2) without raising `UnboundLocalError`. ## Root cause `src/rgb_aura/runtime.py` had `previous_sigterm_handler` assigned only inside the `try` block, after `_connect_and_validate()` succeeded. The `finally` block referenced it unconditionally. If any of the following raised before the assignment: - OpenRGB connection refused / unreachable - `_connect_and_validate()` device mapping validation error - `_build_runtime_zones()` validation error ...then the `finally` block raised `UnboundLocalError: cannot access local variable 'previous_sigterm_handler'`, which masked the original startup exception and made troubleshooting harder. ## Fix One-line addition: initialize the variable to `None` before the `try`. The existing `if previous_sigterm_handler is not None:` guard in the `finally` now correctly skips the SIGTERM restore when the handler was never registered. ## Regression test `tests/test_runtime.py::test_run_combined_runtime_returns_mapping_error_when_validation_fails` - Monkeypatches `_connect_and_validate` to raise `DeviceMappingError`. - Calls `run_combined_runtime` with otherwise valid runtime args. - Asserts the function returns exit code 2 (mapping error), not raises. - Asserts the SIGTERM handler is left untouched (no leaked global state). Without the fix, this test would fail with `UnboundLocalError` propagating from the `finally` block. With the fix, it passes cleanly. ## Verification before commit - `python -m pytest tests/` — 1 passed. - `ruff check src/ tests/` — all checks passed. - `ruff format --check src/ tests/` — 23 files already formatted. - `python -m rgb_aura.main --dry-run --dry-run-events 3` — clean run, all 14 animations registered, scheduler preview produces events normally. ## Branch workflow - Base branch: `develop` - Work branch: `fix/issue-45-signal-handler-startup-failure` - Pull request target: `develop` - Not merged directly into `main`.
JackFrostbyte deleted branch fix/issue-45-signal-handler-startup-failure 2026-05-13 01:13:18 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
JackFrostbyte/rgb-aura!54
No description provided.