Skip to main content
React Native Video provides a comprehensive error handling system with typed error codes, detailed error messages, and error recovery mechanisms.

Error Types

The library defines several categories of errors that can occur during video playback:

Error Categories

  1. Library Errors - Issues with the video library itself
  2. Player Errors - Problems with the player instance
  3. Source Errors - Issues loading or processing the video source
  4. View Errors - Component-related errors
  5. Unknown Errors - Unclassified errors

Error Classes

The library provides two main error classes:

VideoRuntimeError

Errors that occur during video playback operations.
import { VideoRuntimeError } from 'react-native-video';

try {
  await player.initialize();
} catch (error) {
  if (error instanceof VideoRuntimeError) {
    console.log('Error code:', error.code);
    console.log('Error message:', error.message);
    console.log('Stack trace:', error.stack);
  }
}

VideoComponentError

Errors related to the video component/view.
import { VideoComponentError } from 'react-native-video';

try {
  // Component operations
} catch (error) {
  if (error instanceof VideoComponentError) {
    console.log('Component error:', error.code);
  }
}

Error Codes

All error codes follow a consistent naming pattern: category/specific-error.

Library Errors

library/deallocated
LibraryError
The video library has been deallocated and is no longer available.
library/application-context-not-found
LibraryError
Android-specific: The application context could not be found.

Player Errors

player/released
PlayerError
The player has been released and can no longer be used.
// This will throw player/released error
player.release();
player.play(); // Error: player/released
player/not-initialized
PlayerError
The player has not been initialized yet.
const player = new VideoPlayer({ 
  uri: 'video.mp4',
  initializeOnCreation: false 
});

// Must initialize first
await player.initialize();
player/asset-not-initialized
PlayerError
The video asset has not been initialized.
player/invalid-source
PlayerError
The provided video source is invalid.

Source Errors

source/invalid-uri
SourceError
The video URI is invalid or malformed.
// Invalid URI examples
const player1 = new VideoPlayer({ uri: '' }); // Empty
const player2 = new VideoPlayer({ uri: 'not-a-valid-uri' }); // Malformed
source/missing-read-file-permission
SourceError
The app does not have permission to read the local video file.
Ensure your app has proper file system permissions before attempting to load local videos.
source/file-does-not-exist
SourceError
The specified local video file does not exist.
// File doesn't exist
const player = new VideoPlayer({ 
  uri: 'file:///path/to/nonexistent.mp4' 
});
source/failed-to-initialize-asset
SourceError
Failed to initialize the video asset. This can occur due to:
  • Corrupted video file
  • Unsupported codec
  • Network issues
  • Insufficient memory
source/unsupported-content-type
SourceError
The video format or content type is not supported on this platform.

View Errors

view/not-found
VideoViewError
The video view component could not be found.
view/deallocated
VideoViewError
The video view has been deallocated.
view/picture-in-picture-not-supported
VideoViewError
Picture-in-picture mode is not supported on this device or platform.

Unknown Errors

unknown/unknown
UnknownError
An unclassified error occurred. Check the error message for details.

Handling Errors

Using onError Callback

The recommended way to handle errors is through the onError event listener:
import { VideoPlayer } from 'react-native-video';

const player = new VideoPlayer({
  uri: 'https://example.com/video.mp4',
});

player.onError = (error) => {
  console.log('Error code:', error.code);
  console.log('Error message:', error.message);
  
  // Handle specific errors
  switch (error.code) {
    case 'source/invalid-uri':
      // Show user-friendly message
      showAlert('Invalid video URL');
      break;
      
    case 'source/file-does-not-exist':
      // Attempt to reload or use fallback
      loadFallbackVideo();
      break;
      
    case 'player/not-initialized':
      // Initialize and retry
      await player.initialize();
      break;
      
    default:
      // Generic error handling
      showAlert('Unable to play video');
  }
};
Prevent Error ThrowingWhen an onError callback is provided, the error will not be thrown. This prevents crashes and allows graceful error handling.

Try-Catch Pattern

For async operations, use try-catch blocks:
try {
  await player.initialize();
  await player.replaceSourceAsync({
    uri: 'https://example.com/new-video.mp4',
  });
  player.play();
} catch (error) {
  if (error instanceof VideoRuntimeError) {
    handleVideoError(error);
  } else {
    // Handle unexpected errors
    console.error('Unexpected error:', error);
  }
}

Error Recovery Patterns

Automatic Retry with Exponential Backoff

async function initializeWithRetry(
  player: VideoPlayer,
  maxRetries = 3,
  initialDelay = 1000
) {
  let lastError: Error | null = null;
  
  for (let i = 0; i < maxRetries; i++) {
    try {
      await player.initialize();
      return; // Success
    } catch (error) {
      lastError = error as Error;
      
      if (error instanceof VideoRuntimeError) {
        // Don't retry certain errors
        if ([
          'source/invalid-uri',
          'source/unsupported-content-type',
          'player/released'
        ].includes(error.code)) {
          throw error;
        }
      }
      
      // Wait before retry with exponential backoff
      const delay = initialDelay * Math.pow(2, i);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
  
  throw lastError;
}

// Usage
try {
  await initializeWithRetry(player);
  player.play();
} catch (error) {
  console.error('Failed to initialize after retries:', error);
}

Fallback Source Strategy

const videoSources = [
  'https://cdn1.example.com/video.mp4',
  'https://cdn2.example.com/video.mp4',
  'https://cdn3.example.com/video.mp4',
];

async function loadVideoWithFallback(player: VideoPlayer) {
  for (const uri of videoSources) {
    try {
      await player.replaceSourceAsync({ uri });
      await player.initialize();
      return; // Success
    } catch (error) {
      console.log(`Failed to load from ${uri}:`, error);
      // Try next source
    }
  }
  
  throw new Error('All video sources failed to load');
}

Error Recovery Hook

import { useEffect, useState } from 'react';
import { VideoPlayer, VideoRuntimeError } from 'react-native-video';

function useVideoErrorRecovery(player: VideoPlayer) {
  const [error, setError] = useState<VideoRuntimeError | null>(null);
  const [retryCount, setRetryCount] = useState(0);

  useEffect(() => {
    player.onError = (error) => {
      setError(error);
    };

    return () => {
      player.onError = undefined;
    };
  }, [player]);

  const retry = async () => {
    setError(null);
    setRetryCount(prev => prev + 1);
    
    try {
      await player.initialize();
      player.play();
    } catch (err) {
      // Error will be caught by onError listener
    }
  };

  const reset = () => {
    setError(null);
    setRetryCount(0);
  };

  return { error, retryCount, retry, reset };
}

// Usage in component
function VideoComponent() {
  const [player] = useState(() => new VideoPlayer({ uri: 'video.mp4' }));
  const { error, retryCount, retry, reset } = useVideoErrorRecovery(player);

  if (error) {
    return (
      <View>
        <Text>Error: {error.message}</Text>
        <Text>Code: {error.code}</Text>
        {retryCount < 3 && (
          <Button title="Retry" onPress={retry} />
        )}
        <Button title="Reset" onPress={reset} />
      </View>
    );
  }

  return <VideoView player={player} />;
}

Error Logging and Monitoring

Structured Error Logging

function logVideoError(error: VideoRuntimeError, context: Record<string, any>) {
  const errorLog = {
    timestamp: new Date().toISOString(),
    code: error.code,
    message: error.message,
    stack: error.stack,
    context,
  };
  
  // Send to analytics service
  analytics.logError('video_playback_error', errorLog);
  
  // Log to console in development
  if (__DEV__) {
    console.error('Video Error:', errorLog);
  }
}

// Usage
player.onError = (error) => {
  logVideoError(error, {
    videoUri: player.source.uri,
    playerStatus: player.status,
    currentTime: player.currentTime,
    platform: Platform.OS,
  });
};

Best Practices

Always Provide onError HandlerAlways set up an onError handler to prevent crashes and provide graceful degradation.
Check Error Codes Before RetrySome errors like source/invalid-uri or player/released should not be retried. Check the error code before implementing retry logic.
Provide User FeedbackShow user-friendly error messages instead of raw error codes. Give users actionable options like retry or contact support.
Log Errors for MonitoringImplement error logging to track error patterns and identify systemic issues in production.
Test Error ScenariosTest your error handling with:
  • Invalid URIs
  • Network failures
  • Unsupported formats
  • Missing permissions
  • Released players

TypeScript Types

type LibraryError =
  | 'library/deallocated'
  | 'library/application-context-not-found';

type PlayerError =
  | 'player/released'
  | 'player/not-initialized'
  | 'player/asset-not-initialized'
  | 'player/invalid-source';

type SourceError =
  | 'source/invalid-uri'
  | 'source/missing-read-file-permission'
  | 'source/file-does-not-exist'
  | 'source/failed-to-initialize-asset'
  | 'source/unsupported-content-type';

type VideoViewError =
  | 'view/not-found'
  | 'view/deallocated'
  | 'view/picture-in-picture-not-supported';

type UnknownError = 'unknown/unknown';

type VideoErrorCode =
  | LibraryError
  | PlayerError
  | SourceError
  | VideoViewError
  | UnknownError;

class VideoError<TCode extends VideoErrorCode> extends Error {
  readonly code: TCode;
  readonly message: string;
  readonly stack?: string;
}

class VideoComponentError extends VideoError<VideoViewError> {}

class VideoRuntimeError extends VideoError<
  LibraryError | PlayerError | SourceError | UnknownError
> {}