Skip to content

fix: make YouTube player errors readable by users - #591

Open
FelipeDefensor wants to merge 2 commits into
devfrom
fix/youtube-error-messages
Open

fix: make YouTube player errors readable by users#591
FelipeDefensor wants to merge 2 commits into
devfrom
fix/youtube-error-messages

Conversation

@FelipeDefensor

Copy link
Copy Markdown
Collaborator

Why

Every branch of onError in the YouTube player quoted the IFrame API reference verbatim. The most common failure — a URL whose video id YouTube doesn't recognise — comes back as error code 2, whose documented text reads:

The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.

Paste https://www.youtube.com/watch?v=zzzzzzzzzzz and that is what you get: a lecture about character counts, for an id that is exactly eleven valid characters. The message contradicts the input.

Found while building a repro bundle for #450. Pre-existing on dev, unrelated to that PR's feature work, so it is branched off dev and can land independently.

What changes

Messages say what happened and what to try. Code 2 and code 100 are worded so either can appear for an unknown id without misleading the reader, since YouTube uses 2 for ids it merely doesn't recognise as well as for malformed ones.

The default branch is fixed. It used a plain string, so it printed the literal ${event.data} instead of the error code.

The malformed case gets named. YouTubePlayer.is_well_formed_id checks the id against [\w-]{11} and, when it can't be a video id at all, display_error says so instead of relaying YouTube's answer — so a typo and a deleted video no longer produce the same message.

The id check never blocks a load

Deliberate, and the reason is worth stating because the obvious implementation is worse.

Eleven characters of [A-Za-z0-9_-] has held since YouTube launched, but Google documents the id as an opaque string and has never promised a length. So VIDEO_ID_PATTERN is used only to choose an error message. If the format ever widens, the specific message stops appearing and everything falls back to today's behaviour — no valid URL is ever refused, and no release is needed to unbreak it.

That is not hypothetical caution. The same class of assumption is already broken next door, on the URL side:

https://www.youtube.com/shorts/dQw4w9WgXcQ  ->  'shorts'
https://www.youtube.com/live/dQw4w9WgXcQ    ->  'live'
https://www.youtube.com/watch?v=dQw4w9WgXcQ ->  'dQw4w9WgXcQ'

YOUTUBE_URL_REGEX matches Shorts and Live URLs and then extracts the path segment as the video id, so those links fail today. This PR does not fix that — it only means such a URL now produces a message about the address rather than one about asterisks. Flagging it for a separate change.

Tests

tests/player/test_youtube_player.py pins the id-shape assumption, including the shorts / live values the regex currently mis-extracts, so a change in either place shows up as a test failure rather than silently.

Full suite on this branch: 2 failed / 1850 passed. Both failures are tests/test_app.py::TestOpen cases that also fail on dev under -n auto and pass serially — the known parallel-run flakiness, not this change.

Repro bundle

The fixture is any .tla whose media_path is a YouTube URL with a bad id — generate one by saving a file with a valid YouTube URL through the CLI, then swapping media_path (don't hand-author the JSON, it drifts from the real serialization format).

uv run --python 3.12 tilia "$PWD/repro/yt-missing-video.tla"

Acceptance criteria — unrecognised id (watch?v=zzzzzzzzzzz, eleven valid characters):

  • Do: launch with the fixture as the first file of the session.
  • Was: "…a video ID that does not have 11 characters, or … invalid characters, such as exclamation points or asterisks."
  • Now: "YouTube did not accept this video ID. Check that the address is a link to an existing video."

Acceptance criteria — malformed id (watch?v=abc):

  • Do: same.
  • Was: identical text to the case above — the two were indistinguishable.
  • Now: "This does not look like the address of a YouTube video. Check the URL: the video id is the eleven-character code after 'watch?v=' or 'youtu.be/'."

HEAD~1 is the message rewrite alone, without the id check, if you want to see the two effects separately.

Note for #450

#450 touches the same default: line in onError (it fixes the template literal too), so whichever lands second will hit a one-hunk conflict there. Trivial to resolve.

The five onError branches quoted the IFrame API reference verbatim, so a
user who pasted a perfectly ordinary URL was told about "a video ID that
does not have 11 characters, or ... invalid characters, such as
exclamation points or asterisks". YouTube also returns code 2 for ids it
simply does not recognise, not only for malformed ones, so that text
contradicted the input in the most common failure case.

Rewrite the messages to say what happened and what to try. Code 2 and
code 100 are now phrased so either can appear for an unknown id without
misleading the reader.

Also fixes the default branch, which used a plain string and so printed
the literal "${event.data}" instead of the error code.
YouTube returns error code 2 both for ids it cannot parse and for ids it
simply does not have, so its own message cannot tell a typo apart from a
deleted video. When the id we extracted cannot be a video id at all, say
that instead of relaying YouTube's answer.

The check never blocks a load. The eleven-character shape has held since
YouTube launched but was never promised, so if it ever widens the only
consequence is that this message stops appearing -- loads keep working
and the behaviour falls back to what it is today. VIDEO_ID_PATTERN and
is_well_formed_id carry that reasoning so a future reader knows the
check is advisory.

Also covers the ids get_id_from_url currently returns for /shorts/ and
/live/ URLs ("shorts", "live"), which the regex mis-extracts -- those now
produce a message about the address rather than one about the video.
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