Skip to content

fix(cues): classify a cue's media without raising; editor raises named, engine logs (869fej07m) - #16

Merged
ibiltari merged 1 commit into
mainfrom
fix/869fej07m-media-guards
Oct 8, 2026
Merged

ibiltari merged 1 commit into
mainfrom
fix/869fej07m-media-guards

Conversation

@ibiltari

@ibiltari ibiltari commented Oct 8, 2026

Copy link
Copy Markdown
Member

What

MediaCue.media_status() → ('none' | 'invalid' | 'ok', file_name), a non-raising classifier, and the two readers of a cue's media use it with different behaviours:

  • CueList.get_media (editor path: update, new, duplicate, relink): a media block without a usable file (invalid) raises a named ValueError that says which cue; no media object at all (None, what an empty <Media/> or JSON Media: null decodes to) is logged at WARNING and skipped, so legacy projects stay listable and duplicable.
  • CuemsScript.get_own_media (engine path, every node, every load): never raises — both shapes are logged at ERROR and left out; the project still loads and that cue fails at arm, locally, as an empty <Media/> always did.

Why

Both guarded with hasattr(cue.media, 'file_name'), but file_name is a property that raises KeyError, which hasattr does not catch. A client that drops a cue's media block (the UI does when the file is not in its library list) produced an empty Media object and the editor's save died with a bare KeyError 'file_name' inside the atomic block. Silently skipping instead would have let the save write an empty <Media/> and lose the cue's media; raising in the engine path would have made such a project unloadable on every node (first and second Opus reviews of the plan, cuems-RELATIONS/Plans/2026-10-08-edit-save-media-listupdate-cache-bridge-names.md).

Verification

19 new tests (tests/test_media_guards.py): both functions × {None, {}, missing/empty file_name, missing id, good}, nested CueLists, the <Media/>-as-None shape; suite 625 passed on test2's venv. Ruff: no new findings (CI runs pytest only).

Version 0.1.0rc16. Companion changes: cuems-editor (validator before any write), cuems-frontend (never drops the block). ClickUp 869fej07m.

…d, engine logs (869fej07m)

Both readers of a cue's media guarded with hasattr(cue.media, 'file_name'),
but file_name is a property that raises KeyError, which hasattr does not
catch. A client that drops a cue's media block (the UI does when the file is
not in its library list) produced an empty Media object and the editor's save
died inside the atomic block with a bare KeyError 'file_name'.

- MediaCue.media_status() -> ('none' | 'invalid' | 'ok', file_name): the
  non-raising classifier. 'none' is no media object at all (an empty <Media/>
  or JSON Media: null decode to None); 'invalid' is a media block without a
  file_name key, with an empty file_name, or without an id key.
- CueList.get_media (editor path: update, new, duplicate, relink): 'invalid'
  raises a named ValueError that says which cue, so a save that dropped the
  media never gets written; 'none' is logged at WARNING and skipped so legacy
  projects stay listable and duplicable (refusing to save that shape is the
  editor validator's job).
- CuemsScript.get_own_media (engine path, every node, every load): never
  raises; both shapes are logged at ERROR and left out of the media list, the
  project still loads and that cue fails at arm, locally, as an empty
  <Media/> always did.

Version 0.1.0rc16. Suite 625 passed (test2 venv).
@codecov

codecov Bot commented Oct 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.64430% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/cuemsutils/cues/CuemsScript.py 75.00% 0 Missing and 2 partials ⚠️
src/cuemsutils/cues/MediaCue.py 80.00% 1 Missing and 1 partial ⚠️
tests/test_media_guards.py 99.18% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@ibiltari
ibiltari merged commit 2dd23b3 into main Oct 8, 2026
3 checks passed
@ibiltari
ibiltari deleted the fix/869fej07m-media-guards branch October 9, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant