Handle partial query failures in refresh()#20
Merged
SteveEasley merged 3 commits intoSteveEasley:mainfrom Apr 5, 2026
Merged
Conversation
Add missing error code 028 (ERROR_INCOMPATIBLE_VIDEO_CONFIG) to the protocol constants, per the Kaleidescape Control Protocol Reference Manual. Use return_exceptions=True in refresh() so that a single query failure doesn't discard results from the other 6 queries. Log a warning for each failed query and continue applying successful results. Devices that lack masking calibration return error 028 for GET_SCREEN_MASK2, and devices not in CinemaScope mode return the same error for GET_CINEMASCAPE_MASK. Previously this caused asyncio.gather to raise, discarding all 7 query results including the successful ones.
The loop-based approach with heterogeneous updater functions caused a mypy "Cannot call function of unknown type" error. Use explicit isinstance checks for each result instead, matching the existing code style in _handle_event().
SteveEasley
pushed a commit
that referenced
this pull request
May 6, 2026
PR #18 (Refresh device state after auto-reconnect) added two tests that wait on `connect_signal` (STATE_CONNECTED) after the initial connect. PR #19 (Dispatch STATE_CONNECTED only on auto-reconnect) then moved the STATE_CONNECTED dispatch out of `_connect()` and into `_reconnect()`. PR #19 updated other tests with the same pattern, but #19 was opened before #18 merged, so the two tests added by #18 weren't updated. Result: `await connect_signal.wait()` after initial connect waits forever, hanging CI for the full 6h job timeout. Every CI run on main since #18 has been cancelled this way (#19, #20, #21, v1.1.6, #22). Match the pattern used by other tests updated in #19: assert `state == STATE_CONNECTED` directly after the initial connect, and keep `connect_signal.wait()` only for the post-reconnect signal where STATE_CONNECTED is actually dispatched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ERROR_INCOMPATIBLE_VIDEO_CONFIG) to the protocol constants, per the Kaleidescape Control Protocol Reference Manualreturn_exceptions=Trueinrefresh()so that a single query failure doesn't discard results from the other 6 queriesProblem
refresh()runs 7 state queries viaasyncio.gather()withoutreturn_exceptions=True. If any single query fails, the entire gather raises and none of the_update_*calls execute — even for queries that completed successfully.In practice,
GET_SCREEN_MASK2returns error 028 ("Incompatible video configuration") on devices that lack masking calibration, andGET_CINEMASCAPE_MASKreturns the same error when not in CinemaScope mode (documented on p. 173 of the Control Protocol Reference Manual). This causesrefresh()to discard all results, leaving the device state unpopulated.Test plan
test_refresh_partial_failureregistersGET_SCREEN_MASK2to return error 028 and verifies the other 6 query results are still applied to the device state