Skip to content

feat(core): add error handling to Hls.js media#1164

Merged
luwes merged 2 commits intomainfrom
hls-errors
Apr 1, 2026
Merged

feat(core): add error handling to Hls.js media#1164
luwes merged 2 commits intomainfrom
hls-errors

Conversation

@luwes
Copy link
Copy Markdown
Collaborator

@luwes luwes commented Mar 31, 2026

  • This adds basic error conversion from Hls.js fatal errors to the HTMLMediaElement error standard.
  • Adds our own MediaError class with consistent messages.

Note

Medium Risk
Introduces new error propagation and event-bridging behavior in core delegate/proxy media layers, which can change how media events/errors surface to consumers. Risk is moderate because it touches shared mixins used across multiple media delegates, though changes are localized and covered by new tests.

Overview
Adds a new MediaError class (with HTMLMediaElement-like codes/messages) and an HlsMediaErrorsMixin that converts fatal hls.js errors into ErrorEvent('error') dispatches while exposing the current error via an error getter.

Updates HLS delegates (HlsJsMediaDelegate, HlsMediaDelegate, NativeHlsMediaDelegate) to be EventTargets, forward delegate events to the host via new bridgeEvents, and surface error from the active engine/target. Also refactors delegate-prop inference types into core/media/types.ts, and adds vitest coverage for event forwarding and HLS error mapping/reset behavior.

Written by Cursor Bugbot for commit 89fc5d3. This will update automatically on new commits. Configure here.

@luwes luwes self-assigned this Mar 31, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Mar 31, 2026 11:24pm

Request Review

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 31, 2026

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 89fc5d3
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/69cc57abce53a00008f05240
😎 Deploy Preview https://deploy-preview-1164--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

📦 Bundle Size Report

🎨 @videojs/html

Path Base PR Diff %
/media/hls-video 132.65 kB 133.01 kB +371 B +0.3% 🔺
/media/mux-video 155.33 kB 155.78 kB +458 B +0.3% 🔺
/video (default + hls) 154.91 kB 155.50 kB +604 B +0.4% 🔺
/video (minimal + hls) 154.86 kB 155.44 kB +596 B +0.4% 🔺
Presets (7)
Entry Size
/video (default) 23.95 kB
/video (default + hls) 155.50 kB
/video (minimal) 23.87 kB
/video (minimal + hls) 155.44 kB
/audio (default) 21.95 kB
/audio (minimal) 21.98 kB
/background 6.81 kB
Media (7)
Entry Size
/media/background-video 1.04 kB
/media/container 1.59 kB
/media/dash-video 236.19 kB
/media/hls-video 133.01 kB
/media/mux-video 155.78 kB
/media/native-hls-video 2.98 kB
/media/simple-hls-video 14.95 kB
Players (3)
Entry Size
/video/player 6.54 kB
/audio/player 6.54 kB
/background/player 6.53 kB
Skins (16)
Entry Type Size
/video/minimal-skin.css css 3.42 kB
/video/skin.css css 3.44 kB
/video/minimal-skin js 23.03 kB
/video/minimal-skin.tailwind js 23.52 kB
/video/skin js 23.13 kB
/video/skin.tailwind js 23.55 kB
/audio/minimal-skin.css css 2.40 kB
/audio/skin.css css 2.37 kB
/audio/minimal-skin js 21.19 kB
/audio/minimal-skin.tailwind js 21.54 kB
/audio/skin js 21.18 kB
/audio/skin.tailwind js 21.56 kB
/background/skin.css css 117 B
/background/skin js 1.14 kB
/base.css css 157 B
/shared.css css 86 B
UI Components (21)
Entry Size
/ui/alert-dialog 1.86 kB
/ui/alert-dialog-close 1.65 kB
/ui/alert-dialog-description 1.59 kB
/ui/alert-dialog-title 1.61 kB
/ui/buffering-indicator 1.67 kB
/ui/captions-button 1.92 kB
/ui/controls 1.69 kB
/ui/fullscreen-button 1.84 kB
/ui/mute-button 1.86 kB
/ui/pip-button 1.89 kB
/ui/play-button 1.86 kB
/ui/playback-rate-button 1.88 kB
/ui/popover 2.58 kB
/ui/poster 1.55 kB
/ui/seek-button 1.90 kB
/ui/slider 2.18 kB
/ui/thumbnail 1.95 kB
/ui/time 1.69 kB
/ui/time-slider 2.14 kB
/ui/tooltip 2.14 kB
/ui/volume-slider 2.28 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react

Path Base PR Diff %
/media/hls-video 132.51 kB 133.02 kB +526 B +0.4% 🔺
/media/mux-video 155.16 kB 155.60 kB +452 B +0.3% 🔺
/video (default + hls) 150.59 kB 151.13 kB +551 B +0.4% 🔺
/video (minimal + hls) 150.51 kB 151.16 kB +665 B +0.4% 🔺
Presets (7)
Entry Size
/video (default) 19.27 kB
/video (default + hls) 151.13 kB
/video (minimal) 19.32 kB
/video (minimal + hls) 151.16 kB
/audio (default) 16.09 kB
/audio (minimal) 16.17 kB
/background 3.13 kB
Media (6)
Entry Size
/media/background-video 476 B
/media/dash-video 236.43 kB
/media/hls-video 133.02 kB
/media/mux-video 155.60 kB
/media/native-hls-video 2.91 kB
/media/simple-hls-video 14.91 kB
Skins (14)
Entry Type Size
/video/minimal-skin.css css 3.42 kB
/video/skin.css css 3.44 kB
/video/minimal-skin js 19.23 kB
/video/minimal-skin.tailwind js 22.70 kB
/video/skin js 19.20 kB
/video/skin.tailwind js 22.80 kB
/audio/minimal-skin.css css 2.40 kB
/audio/skin.css css 2.37 kB
/audio/minimal-skin js 16.08 kB
/audio/minimal-skin.tailwind js 18.54 kB
/audio/skin js 16.01 kB
/audio/skin.tailwind js 18.55 kB
/background/skin.css css 90 B
/background/skin js 272 B
UI Components (18)
Entry Size
/ui/alert-dialog 1.50 kB
/ui/buffering-indicator 1.91 kB
/ui/captions-button 1.70 kB
/ui/controls 1.25 kB
/ui/fullscreen-button 2.31 kB
/ui/mute-button 1.70 kB
/ui/pip-button 1.69 kB
/ui/play-button 1.70 kB
/ui/playback-rate-button 1.71 kB
/ui/popover 2.92 kB
/ui/poster 1.75 kB
/ui/seek-button 2.34 kB
/ui/slider 3.16 kB
/ui/thumbnail 2.10 kB
/ui/time 1.95 kB
/ui/time-slider 2.78 kB
/ui/tooltip 1.87 kB
/ui/volume-slider 2.66 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core

Path Base PR Diff %
/dom/media/hls 132.06 kB 132.52 kB +476 B +0.4% 🔺
/dom/media/mux 154.71 kB 155.36 kB +660 B +0.4% 🔺
Entries (8)
Entry Size
. 5.07 kB
/dom 8.75 kB
/dom/media/custom-media-element 1.81 kB
/dom/media/dash 235.62 kB
/dom/media/hls 132.52 kB
/dom/media/mux 155.36 kB
/dom/media/native-hls 2.32 kB
/dom/media/simple-hls 14.30 kB
🏷️ @videojs/element — no changes
Entries (2)
Entry Size
. 999 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Size
. 1.39 kB
/html 696 B
/react 360 B
🔧 @videojs/utils — no changes
Entries (10)
Entry Size
/array 104 B
/dom 1.25 kB
/events 319 B
/function 261 B
/object 247 B
/predicate 265 B
/string 148 B
/style 190 B
/time 478 B
/number 158 B
📦 @videojs/spf — no changes
Entries (3)
Entry Size
. 40 B
/dom 12.45 kB
/playback-engine 12.41 kB

ℹ️ How to interpret

All sizes are standalone totals (minified + brotli).

Icon Meaning
No change
🔺 Increased ≤ 10%
🔴 Increased > 10%
🔽 Decreased
🆕 New (no baseline)

Run pnpm size locally to check current sizes.

Comment thread packages/core/src/core/media/media-error.ts Outdated
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

if (!data.fatal) return;

const code = hlsErrorTypeToCode[data.type] ?? MediaError.MEDIA_ERR_CUSTOM;
const error = new MediaError(data.error, code, true, data.details);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error object as message adds "Error: " prefix

Medium Severity

Passing data.error (an Error object) as the first argument to new MediaError(data.error, ...) causes the super(message) call to invoke ToString() on the Error, which calls Error.prototype.toString(). This produces "Error: <original message>" instead of just "<original message>". Additionally, if hls.js provides an Error with an empty message, toString() returns "Error" (truthy), preventing defaultMessages from being used as a fallback. Passing data.error?.message instead of data.error would preserve the original message string.

Additional Locations (1)
Fix in Cursor Fix in Web

@luwes luwes merged commit 9e2ede6 into main Apr 1, 2026
21 checks passed
@luwes luwes deleted the hls-errors branch April 1, 2026 00:05
@luwes luwes mentioned this pull request Apr 1, 2026
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