# Error Handling & Resilience Guide

Strategies, error classification, and recovery patterns for handling network stalls, upstream rate limits, and streaming failures.

## Overview Upstream video providers can rotate domains, experience rate limits, or suffer transient outages. This guide explains how Vyla handles errors internally and how client players should respond. --- ## Error Classification - **HTTP 400 Bad Request**: Missing or invalid TMDB ID or episode parameters. Validate input parameters on the client before requesting streams. - **HTTP 429 Too Many Requests**: Upstream host rate limit triggered. The SDK applies backoff delays; clients should respect the `retry_after` header. - **HTTP 502 Bad Gateway**: Upstream host unreachable or timed out. That provider is discarded while other scrapers continue running. - **SSE Disconnect**: Network drop or backgrounded tab. If media is already buffering, do not interrupt. Otherwise, reconnect after a brief delay. - **HLS Fatal Media Error**: Buffer stall or missing encryption key (`fatal: true`). Destroy the player instance and mount the next queued fallback stream. --- ## Client Fallback Strategy Treat stream candidates as a prioritized queue rather than a single static link: 1. **Mount First Candidate**: Mount the first verified source that arrives over SSE. 2. **Queue Subsequent Sources**: Push subsequent incoming `source` events into a fallback array. 3. **Capture Timestamp on Error**: If a fatal error occurs, record `video.currentTime`. 4. **Teardown & Reconnect**: Call `hls.destroy()`, dequeue the next candidate, mount it, and seek back to the saved timestamp once metadata loads. --- ## Implementation Example ```javascript function attachHlsPlayer(videoElement, candidate, fallbackQueue) { const hls = new Hls({ maxBufferLength: 30, maxMaxBufferLength: 60, enableWorker: true }); hls.loadSource(candidate.url); hls.attachMedia(videoElement); hls.on(Hls.Events.ERROR, (event, data) => { if (!data.fatal) return; switch (data.type) { case Hls.ErrorTypes.NETWORK_ERROR: hls.startLoad(); break; case Hls.ErrorTypes.MEDIA_ERROR: hls.recoverMediaError(); break; default: hls.destroy(); if (fallbackQueue.length > 0) { const nextCandidate = fallbackQueue.shift(); const lastTime = videoElement.currentTime; attachHlsPlayer(videoElement, nextCandidate, fallbackQueue); videoElement.addEventListener('loadedmetadata', () => { videoElement.currentTime = lastTime; videoElement.play(); }, { once: true }); } else { showErrorOverlay("All available streaming providers failed."); } break; } }); return hls; } ``` --- ## Timeout Budgets - **First Candidate Timeout (8–10s)**: If no source event arrives within 8 seconds, inform the user that extended search is underway. - **Hard Abort Timeout (20–25s)**: If no viable source is verified before the watchdog timer expires, close the connection and display an empty state with a retry button.