Skip to content

Import

TypeScript
import {
PlayerError,
AuthError,
BrowserPolicyError,
DrmError,
MediaFormatError,
NetworkError,
NotImplementedError,
PluginError,
ResourceError,
StateError,
StreamError,
SEVERITY,
} from '@nomercy-entertainment/nomercy-player-core';

Base: PlayerError

All core and plugin errors descend from PlayerError.

TypeScript
class PlayerError extends Error {
readonly code: string; // string id: 'core:auth/forbidden', 'fillz:viz/...'
readonly id?: number; // optional numeric id from the registry
readonly severity: Severity; // 'fatal' | 'error' | 'warning' | 'info'
readonly scope: ErrorScope; // discriminated union: { kind: 'core' } | { kind: 'plugin', id }
readonly cause?: unknown; // chained underlying error
readonly context?: Record<string, unknown>; // track id, time, url, status, etc.
readonly suggestion?: string; // actionable hint for the user

isHttp(century: 1 | 2 | 3 | 4 | 5): boolean;
}

ErrorScope:

TypeScript
type ErrorScope =
| { kind: 'core' }
| { kind: 'backend'; id: 'audio-element' | 'webaudio' | 'video' | 'html5' | 'mse' | 'webcodecs' }
| { kind: 'stream'; id: 'native' | 'hls' | 'dash' }
| { kind: 'cue'; id: 'lrc' | 'vtt' | 'sprite-vtt' | 'ttml' }
| { kind: 'network' }
| { kind: 'auth' }
| { kind: 'plugin'; id: string };

StateError

Thrown when a player method is called in an invalid lifecycle state (e.g. transport before setup(), setup() called twice).

Common codes: core:player/not-ready, core:player/disposed, core:lifecycle/already-setup, core:plugin/duplicate-id

AuthError

Thrown by the auth pipeline when token acquisition or refresh fails.

Common codes: core:auth/forbidden, core:auth/refresh-failed

NetworkError

Thrown by authFetch on network failures (no response received, not 4xx/5xx). Carries context.url.

MediaFormatError

Thrown when a media item cannot be loaded due to missing or malformed data.

Common codes: core:media/missing-url, core:media/codec-unsupported, core:media/load-failed

StreamError

Thrown by stream backends when a fatal stream-level error occurs.

ResourceError

Thrown when a remote resource (subtitle file, playlist, license) cannot be fetched or parsed.

DrmError

Thrown by DRM plugins when EME key acquisition fails.

BrowserPolicyError

Thrown when a browser API is unavailable (not supported in this browser/environment).

Common codes:

CodeCause
core:policy/wakeLockUnsupportedScreen Wake Lock API absent
core:policy/setSinkIdUnsupportedsetSinkId not supported
core:policy/castUnavailableCast SDK not loaded
core:policy/castLoadTimeoutSDK load timed out
core:policy/airplayUnavailableAirPlay is WebKit-only
core:policy/remotePlaybackUnavailableRemotePlayback API absent
core:policy/audioOutputPickerUnsupportedselectAudioOutput is Chrome 105+ only
core:policy/fullscreenUnsupportedFullscreen API absent
core:policy/pipUnsupportedPiP API absent

PluginError

Thrown by the plugin runtime when registration constraints are violated.

Common codes: core:plugin/duplicate-id, core:plugin/missing-dep, core:plugin/version-mismatch, core:plugin/incompatible-core-version, core:plugin/init-timeout

NotImplementedError

Thrown by methods intentionally not implemented for a given library (e.g. subtitles() on the music player).

Common codes: core:not-implemented/<method>

Severity

TypeScript
type Severity = 'fatal' | 'error' | 'warning' | 'info';

const SEVERITY = {
FATAL: 'fatal',
ERROR: 'error',
WARNING: 'warning',
INFO: 'info',
} as const;
  • fatal: unrecoverable; player shutting down
  • error: recoverable problem
  • warning / info: observability only

PlayerErrorEvent

The shape carried on fatal, error, warning, and info events:

TypeScript
interface PlayerErrorEvent {
error: PlayerError;
severity: Severity;
scope: ErrorScope;
timestamp: number;
markHandled(): void;
isHandled(): boolean;
stopImmediatePropagation(): void;
isPropagationStopped(): boolean;
preventDefault(): void;
isDefaultPrevented(): boolean;
}

Retry policy

Per-call retry behaviour is a RetryConfig; a full policy is a map of error-code matcher to RetryConfig:

TypeScript
interface RetryConfig {
attempts: number; // 0 = never retry
backoff?: 'linear' | 'exponential';
baseMs?: number;
maxMs?: number;
refreshFirst?: boolean; // run the auth refresh before the first retry (used for 401s)
}

type IRetryPolicy = Record<string, RetryConfig>;

See also