VideoError
Base error class for React Native Video errors. All video-related errors extend this class.
class VideoError<TCode extends VideoErrorCode> extends Error {
readonly code: TCode;
readonly message: string;
readonly stack?: string;
}
Properties
The error code identifying the specific error type. See VideoErrorCode for possible values.
Human-readable description of the error.
Stack trace for debugging (when available).
Error Classes
VideoComponentError
Errors related to the Video component itself:
class VideoComponentError extends VideoError<VideoViewError> {}
Thrown when there are issues with the video view/component.
VideoRuntimeError
Errors that occur during video playback:
class VideoRuntimeError extends VideoError<
LibraryError | PlayerError | SourceError | UnknownError
> {}
Thrown when there are runtime issues with the library, player, or video source.
VideoErrorCode
Union type of all possible error codes:
type VideoErrorCode =
| LibraryError
| PlayerError
| SourceError
| VideoViewError
| UnknownError;
LibraryError
Errors related to the video library itself:
type LibraryError =
| 'library/deallocated'
| 'library/application-context-not-found';
The video library has been deallocated/destroyed.
library/application-context-not-found
Android: Application context could not be found.
PlayerError
Errors related to the video player:
type PlayerError =
| 'player/released'
| 'player/not-initialized'
| 'player/asset-not-initialized'
| 'player/invalid-source';
The player has been released and cannot be used.
The player has not been initialized yet.
player/asset-not-initialized
The video asset has not been initialized.
The provided video source is invalid.
SourceError
Errors related to video source loading:
type SourceError =
| 'source/invalid-uri'
| 'source/missing-read-file-permission'
| 'source/file-does-not-exist'
| 'source/failed-to-initialize-asset'
| 'source/unsupported-content-type';
The video URI is invalid or malformed.
source/missing-read-file-permission
Missing permission to read the video file.
source/file-does-not-exist
The video file does not exist at the specified path.
source/failed-to-initialize-asset
Failed to initialize the video asset.
source/unsupported-content-type
The video content type is not supported.
VideoViewError
Errors related to the video view/component:
type VideoViewError =
| 'view/not-found'
| 'view/deallocated'
| 'view/picture-in-picture-not-supported';
The video view could not be found.
The video view has been deallocated.
view/picture-in-picture-not-supported
Picture-in-picture mode is not supported on this device/platform.
UnknownError
Unknown or unexpected errors:
type UnknownError = 'unknown/unknown';
An unknown error occurred.
Error Handling
Basic Error Handling
import { VideoPlayer, VideoError, tryParseNativeVideoError } from 'react-native-video';
try {
const player = VideoPlayer.create({
uri: 'https://example.com/video.mp4'
});
await player.playAsync();
} catch (error) {
const videoError = tryParseNativeVideoError(error);
if (videoError instanceof VideoError) {
console.error(`[${videoError.code}]: ${videoError.message}`);
} else {
console.error('Unknown error:', error);
}
}
Handling Specific Error Types
import {
VideoPlayer,
VideoComponentError,
VideoRuntimeError,
tryParseNativeVideoError
} from 'react-native-video';
try {
const player = VideoPlayer.create({
uri: 'https://example.com/video.mp4'
});
await player.playAsync();
} catch (error) {
const videoError = tryParseNativeVideoError(error);
if (videoError instanceof VideoComponentError) {
// Handle component errors
console.error('Component error:', videoError.message);
if (videoError.code === 'view/picture-in-picture-not-supported') {
console.log('PiP not available on this device');
}
} else if (videoError instanceof VideoRuntimeError) {
// Handle runtime errors
console.error('Runtime error:', videoError.message);
if (videoError.code === 'source/file-does-not-exist') {
console.log('Video file not found');
}
} else {
console.error('Unknown error:', error);
}
}
Handling Specific Error Codes
import { VideoPlayer, VideoError, tryParseNativeVideoError } from 'react-native-video';
const handleVideoError = (error: unknown) => {
const videoError = tryParseNativeVideoError(error);
if (!(videoError instanceof VideoError)) {
console.error('Unknown error:', error);
return;
}
switch (videoError.code) {
case 'source/invalid-uri':
console.error('Invalid video URL');
break;
case 'source/file-does-not-exist':
console.error('Video file not found');
break;
case 'source/missing-read-file-permission':
console.error('Missing file read permission');
break;
case 'player/not-initialized':
console.error('Player not initialized');
break;
case 'view/picture-in-picture-not-supported':
console.error('PiP not supported');
break;
case 'library/deallocated':
console.error('Video library deallocated');
break;
default:
console.error(`Error [${videoError.code}]: ${videoError.message}`);
}
};
try {
const player = VideoPlayer.create({
uri: 'https://example.com/video.mp4'
});
await player.playAsync();
} catch (error) {
handleVideoError(error);
}
User-Friendly Error Messages
import { VideoError, tryParseNativeVideoError } from 'react-native-video';
import { Alert } from 'react-native';
const getUserFriendlyErrorMessage = (error: unknown): string => {
const videoError = tryParseNativeVideoError(error);
if (!(videoError instanceof VideoError)) {
return 'An unexpected error occurred while playing the video.';
}
const errorMessages: Record<string, string> = {
'source/invalid-uri': 'The video URL is invalid.',
'source/file-does-not-exist': 'The video file could not be found.',
'source/missing-read-file-permission': 'Permission to access the video was denied.',
'source/unsupported-content-type': 'This video format is not supported.',
'player/invalid-source': 'The video source is invalid.',
'view/picture-in-picture-not-supported': 'Picture-in-picture is not available on your device.',
};
return errorMessages[videoError.code] || `Error: ${videoError.message}`;
};
// Usage
try {
await player.playAsync();
} catch (error) {
const message = getUserFriendlyErrorMessage(error);
Alert.alert('Playback Error', message);
}
tryParseNativeVideoError
Utility function to parse native video errors into typed VideoError instances:
function tryParseNativeVideoError<T>(
nativeError: T
): (VideoRuntimeError | VideoComponentError) | T
Attempts to parse an error from native code into a typed JavaScript VideoError. Returns the original error if it cannot be parsed.
Usage
import { tryParseNativeVideoError, VideoError } from 'react-native-video';
try {
await player.playAsync();
} catch (error) {
const parsedError = tryParseNativeVideoError(error);
if (parsedError instanceof VideoError) {
// Typed error with code and message
console.log('Error code:', parsedError.code);
console.log('Error message:', parsedError.message);
} else {
// Original unparsed error
console.error('Unparsed error:', parsedError);
}
}
Examples
Complete Error Handling Example
import React, { useEffect, useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import {
Video,
VideoPlayer,
VideoError,
VideoRuntimeError,
tryParseNativeVideoError
} from 'react-native-video';
const VideoPlayerWithErrorHandling = () => {
const [player, setPlayer] = useState<VideoPlayer | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
try {
const newPlayer = VideoPlayer.create({
uri: 'https://example.com/video.mp4'
});
setPlayer(newPlayer);
} catch (err) {
handleError(err);
}
return () => {
player?.release();
};
}, []);
const handleError = (err: unknown) => {
const videoError = tryParseNativeVideoError(err);
if (videoError instanceof VideoError) {
setError(`[${videoError.code}]: ${videoError.message}`);
// Show user-friendly alert
Alert.alert(
'Playback Error',
getUserFriendlyMessage(videoError.code),
[{ text: 'OK' }]
);
} else {
setError('An unknown error occurred');
}
};
const getUserFriendlyMessage = (code: string): string => {
const messages: Record<string, string> = {
'source/file-does-not-exist': 'Video file not found. Please check the URL.',
'source/invalid-uri': 'Invalid video URL.',
'player/not-initialized': 'Player is not ready yet. Please try again.',
};
return messages[code] || 'Unable to play video.';
};
const handlePlay = async () => {
if (!player) return;
try {
await player.playAsync();
setError(null);
} catch (err) {
handleError(err);
}
};
if (!player) {
return <Text>Loading player...</Text>;
}
return (
<View>
<Video
player={player}
style={{ width: '100%', height: 300 }}
/>
{error && (
<View style={{ padding: 16, backgroundColor: '#ffebee' }}>
<Text style={{ color: '#c62828' }}>{error}</Text>
</View>
)}
<Button title="Play" onPress={handlePlay} />
</View>
);
};
export default VideoPlayerWithErrorHandling;