Files
documentation/guides/error-handling.md

83 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Error Handling & Resilience Guide
<p class="page-description">Strategies, error classification, and recovery patterns for handling network stalls, upstream rate limits, and streaming failures.</p>
## 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.