diff --git a/docs/tutorials/errors.md b/docs/tutorials/errors.md new file mode 100644 index 0000000000..4d553e89e0 --- /dev/null +++ b/docs/tutorials/errors.md @@ -0,0 +1,90 @@ +# Error Handling + +The basics for handling native Error and {@link shaka.util.Error} thrown by Shaka. + +## Listening To and Handling Errors + +```typescript +const handleError = (error) => { + if (error instanceof Error) { + // shaka crashed with an unhandled native error + } + + if (error.severity === shaka.util.Error.Severity.CRITICAL) { + // handle fatal error, playback can not continue + } else { + // handle non-fatal error, playback can continue + } +}; + +const player = new shaka.Player(video); + +// handle errors that occur after load +player.addEventListener("error", handleError); + +// handle errors that occur during load + +// listening directly on the promise +player.load(url).catch(handleError); + +// listening with async/await +try { + await player.load(url); +} catch (e) { + errorHandler(e); +} +``` + +## Custom Handling of Streaming Errors + +The `streaming.failureCallback` property of ({@link shaka.extern.PlayerConfiguration}) can be used to add custom handling or error conversion of errors that occur during streaming. + +```typescript +player.configure("streaming.failureCallback", (error) => { + if (error.severity === shaka.util.Error.Severity.CRITICAL) { + // custom handling of critical error + // e.g. player.retryStreaming(); + } else { + // custom handling of recoverable error + } +}); +``` + +## Custom Handling of Retries + +When configuring retry parameters in Shaka there may be known error codes that should not be retried, or the need to break out of an infinite retry loop in a live context. Retries for failed network requests are not reported as `RECOVERABLE` errors. + +For example, if a VOD manifest is missing, unlike when a LIVE manifest is missing, it can be expected to not show up and there is no need to retry. + +This is how to convert a retry into a critical error: + +```typescript +const nwEngine = player.getNetworkingEngine(); + +const vodManifestNotFoundHandler = (error) => { + const { + error: { code, data }, + } = error; + + if (code === shaka.util.Error.Code.BAD_HTTP_STATUS) { + if ( + Array.isArray(data) && + data[1] === 404 && + data[4] === shaka.net.NetworkingEngine.RequestType.MANIFEST + ) { + throw new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.NETWORK, + "MANIFEST_NOT_FOUND", + ) + } + } +}; + +nwEngine.addEventListener("retry", vodManifestNotFoundHandler); + +player.addEventListener("loaded", () => { + nwEngine.removeEventListener("retry", vodManifestNotFoundHandler); +}); + +```