From 18aaa870e7b6ea751afb59c0cef3e10422573611 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Oct 2025 19:33:53 +0530 Subject: [PATCH 1/2] feat(adapters): provide detailed availability info and install guidance for expo-av/expo-video --- ENHANCED_ERROR_HANDLING.md | 99 ++++++++++++ package-lock.json | 4 +- src/adapters/ExpoAVVideoAdapter.tsx | 37 ++++- src/adapters/ExpoVideoAdapter.tsx | 29 +++- src/adapters/FallbackVideoAdapter.tsx | 16 ++ src/adapters/__tests__/ErrorHandling.test.ts | 150 +++++++++++++++++++ src/adapters/types.ts | 10 ++ 7 files changed, 332 insertions(+), 13 deletions(-) create mode 100644 ENHANCED_ERROR_HANDLING.md create mode 100644 src/adapters/__tests__/ErrorHandling.test.ts diff --git a/ENHANCED_ERROR_HANDLING.md b/ENHANCED_ERROR_HANDLING.md new file mode 100644 index 0000000..2a3c9d1 --- /dev/null +++ b/ENHANCED_ERROR_HANDLING.md @@ -0,0 +1,99 @@ +# Video Adapter Error Handling Improvements + +This document describes the enhanced error handling for Cloudinary React Native SDK video adapters. + +## Overview + +The video adapters (`ExpoAVVideoAdapter`, `ExpoVideoAdapter`, and `FallbackVideoAdapter`) now provide improved error handling with detailed error messages and installation guidance when video libraries are not available. + +## New Features + +### Enhanced Error Messages + +Instead of generic "module not available" errors, the adapters now provide: +- Specific adapter name in error messages +- Clear installation commands +- Detailed error context + +### New Method: `getAvailabilityInfo()` + +All video adapters now implement an optional `getAvailabilityInfo()` method that returns: + +```typescript +{ + available: boolean; + error?: string; + installationCommand?: string; +} +``` + +### Example Usage + +```typescript +import { VideoPlayerFactory } from 'cloudinary-react-native'; + +const adapter = VideoPlayerFactory.getAvailableAdapter(); + +// Check availability with detailed information +const info = adapter.getAvailabilityInfo?.(); +if (!info?.available) { + console.log(`Error: ${info.error}`); + console.log(`Install with: ${info.installationCommand}`); +} +``` + +## Error Message Examples + +### Before (Generic) +``` +Error: expo-av is not available +``` + +### After (Detailed) +``` +Error: ExpoAVVideoAdapter: Module not found: expo-av. Please install expo-av: "npx expo install expo-av" +``` + +## Benefits + +1. **Better Developer Experience**: Clear error messages with actionable solutions +2. **Faster Debugging**: Specific adapter names and installation commands +3. **Production Safety**: Graceful error handling without silent failures +4. **Non-Breaking**: Existing code continues to work without changes + +## Installation Commands by Adapter + +| Adapter | Installation Command | +|---------|---------------------| +| ExpoAVVideoAdapter | `npx expo install expo-av` | +| ExpoVideoAdapter | `npx expo install expo-video` | +| FallbackVideoAdapter | `npx expo install expo-video expo-av` | + +## Migration Guide + +No migration is required. The new `getAvailabilityInfo()` method is optional and existing error handling continues to work as before, but with improved error messages. + +### Optional: Enhanced Error Handling + +You can optionally use the new method for better error handling: + +```typescript +// Before +try { + const videoComponent = adapter.renderVideo(props, ref); +} catch (error) { + console.error('Video failed:', error.message); +} + +// After (enhanced) +if (!adapter.isAvailable()) { + const info = adapter.getAvailabilityInfo?.(); + if (info && !info.available) { + console.error(`Video adapter error: ${info.error}`); + console.log(`Fix with: ${info.installationCommand}`); + return; + } +} + +const videoComponent = adapter.renderVideo(props, ref); +``` \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 42e8333..2b6e1e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cloudinary-react-native", - "version": "1.2.0", + "version": "1.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cloudinary-react-native", - "version": "1.2.0", + "version": "1.2.1", "license": "MIT", "dependencies": { "@cloudinary/url-gen": "^1.10.0", diff --git a/src/adapters/ExpoAVVideoAdapter.tsx b/src/adapters/ExpoAVVideoAdapter.tsx index 7f20887..939d438 100644 --- a/src/adapters/ExpoAVVideoAdapter.tsx +++ b/src/adapters/ExpoAVVideoAdapter.tsx @@ -3,6 +3,7 @@ import { VideoPlayerAdapter, VideoPlayerProps, VideoPlayerRef, VideoPlayerType } export class ExpoAVVideoAdapter implements VideoPlayerAdapter { private expoAVModule: any = null; + private loadError: Error | null = null; constructor() { this.loadExpoAV(); @@ -12,16 +13,33 @@ export class ExpoAVVideoAdapter implements VideoPlayerAdapter { try { this.expoAVModule = require('expo-av'); } catch (error) { + this.loadError = error as Error; this.expoAVModule = null; } } isAvailable(): boolean { - const hasModule = !!this.expoAVModule; - const hasVideo = !!(this.expoAVModule && this.expoAVModule.Video); - const isAvailable = hasModule && hasVideo; + return !!this.expoAVModule && !!this.expoAVModule.Video; + } + + /** + * Get detailed information about adapter availability + * @returns Object containing availability status, error details, and installation guidance + */ + getAvailabilityInfo(): { + available: boolean; + error?: string; + installationCommand?: string; + } { + if (this.isAvailable()) { + return { available: true }; + } - return isAvailable; + return { + available: false, + error: this.loadError?.message || 'expo-av not installed', + installationCommand: 'npx expo install expo-av' + }; } getAdapterName(): string { @@ -30,7 +48,10 @@ export class ExpoAVVideoAdapter implements VideoPlayerAdapter { renderVideo(props: VideoPlayerProps, ref: RefObject): ReactElement { if (!this.isAvailable()) { - throw new Error('expo-av is not available'); + const info = this.getAvailabilityInfo(); + throw new Error( + `ExpoAVVideoAdapter: ${info.error}. Please install expo-av: "${info.installationCommand}"` + ); } const { Video } = this.expoAVModule; @@ -44,9 +65,9 @@ export class ExpoAVVideoAdapter implements VideoPlayerAdapter { isLooping: false, resizeMode: 'contain', onPlaybackStatusUpdate: props.onPlaybackStatusUpdate, - onError: props.onError || (() => {}), - onLoad: props.onLoad || (() => {}), - onLoadStart: props.onLoadStart || (() => {}), + onError: props.onError, + onLoad: props.onLoad, + onLoadStart: props.onLoadStart, }); } diff --git a/src/adapters/ExpoVideoAdapter.tsx b/src/adapters/ExpoVideoAdapter.tsx index bf0268b..c3e2271 100644 --- a/src/adapters/ExpoVideoAdapter.tsx +++ b/src/adapters/ExpoVideoAdapter.tsx @@ -4,6 +4,7 @@ import { VideoPlayerAdapter, VideoPlayerProps, VideoPlayerRef, VideoPlayerType } export class ExpoVideoAdapter implements VideoPlayerAdapter { private expoVideoModule: any = null; private videoPlayer: any = null; + private loadError: Error | null = null; constructor() { this.loadExpoVideo(); @@ -13,6 +14,7 @@ export class ExpoVideoAdapter implements VideoPlayerAdapter { try { this.expoVideoModule = require('expo-video'); } catch (error) { + this.loadError = error as Error; this.expoVideoModule = null; } } @@ -21,9 +23,27 @@ export class ExpoVideoAdapter implements VideoPlayerAdapter { const hasModule = !!this.expoVideoModule; const hasVideoView = !!(this.expoVideoModule && this.expoVideoModule.VideoView); const hasCreatePlayer = !!(this.expoVideoModule && this.expoVideoModule.createVideoPlayer); - const isAvailable = hasModule && hasVideoView && hasCreatePlayer; + return hasModule && hasVideoView && hasCreatePlayer; + } + + /** + * Get detailed information about adapter availability + * @returns Object containing availability status, error details, and installation guidance + */ + getAvailabilityInfo(): { + available: boolean; + error?: string; + installationCommand?: string; + } { + if (this.isAvailable()) { + return { available: true }; + } - return isAvailable; + return { + available: false, + error: this.loadError?.message || 'expo-video not installed', + installationCommand: 'npx expo install expo-video' + }; } getAdapterName(): string { @@ -32,7 +52,10 @@ export class ExpoVideoAdapter implements VideoPlayerAdapter { renderVideo(props: VideoPlayerProps, ref: RefObject): ReactElement { if (!this.isAvailable()) { - throw new Error('expo-video is not available'); + const info = this.getAvailabilityInfo(); + throw new Error( + `ExpoVideoAdapter: ${info.error}. Please install expo-video: "${info.installationCommand}"` + ); } const { VideoView, createVideoPlayer } = this.expoVideoModule; diff --git a/src/adapters/FallbackVideoAdapter.tsx b/src/adapters/FallbackVideoAdapter.tsx index cb06853..59e1fbe 100644 --- a/src/adapters/FallbackVideoAdapter.tsx +++ b/src/adapters/FallbackVideoAdapter.tsx @@ -17,6 +17,22 @@ export class FallbackVideoAdapter implements VideoPlayerAdapter { return VideoPlayerType.FALLBACK; } + /** + * Get detailed information about adapter availability + * @returns Object containing availability status and installation guidance for video libraries + */ + getAvailabilityInfo(): { + available: boolean; + error?: string; + installationCommand?: string; + } { + return { + available: true, + error: this.errorMessage, + installationCommand: 'npx expo install expo-video expo-av' + }; + } + renderVideo(props: VideoPlayerProps, _ref: RefObject): ReactElement { return React.createElement(View, { style: [ diff --git a/src/adapters/__tests__/ErrorHandling.test.ts b/src/adapters/__tests__/ErrorHandling.test.ts new file mode 100644 index 0000000..ff171a3 --- /dev/null +++ b/src/adapters/__tests__/ErrorHandling.test.ts @@ -0,0 +1,150 @@ +import { ExpoAVVideoAdapter } from '../ExpoAVVideoAdapter'; +import { ExpoVideoAdapter } from '../ExpoVideoAdapter'; +import { FallbackVideoAdapter } from '../FallbackVideoAdapter'; + +describe('Video Adapter Error Handling Improvements', () => { + describe('ExpoAVVideoAdapter', () => { + it('should have getAvailabilityInfo method', () => { + const adapter = new ExpoAVVideoAdapter(); + + expect(typeof adapter.getAvailabilityInfo).toBe('function'); + + const info = adapter.getAvailabilityInfo(); + expect(info).toHaveProperty('available'); + expect(info).toHaveProperty('installationCommand', 'npx expo install expo-av'); + + if (!info.available) { + expect(info).toHaveProperty('error'); + expect(typeof info.error).toBe('string'); + } + }); + + it('should throw descriptive error when rendering video with unavailable module', () => { + const adapter = new ExpoAVVideoAdapter(); + + // Only test if expo-av is actually not available (which it likely isn't in test environment) + if (!adapter.isAvailable()) { + const props = { videoUri: 'test://video.mp4' }; + const ref = { current: null }; + + expect(() => { + adapter.renderVideo(props, ref); + }).toThrow(/ExpoAVVideoAdapter:.*Please install expo-av:/); + } + }); + + it('should provide installation command in error message', () => { + const adapter = new ExpoAVVideoAdapter(); + + if (!adapter.isAvailable()) { + const info = adapter.getAvailabilityInfo(); + expect(info.installationCommand).toBe('npx expo install expo-av'); + } + }); + }); + + describe('ExpoVideoAdapter', () => { + it('should have getAvailabilityInfo method', () => { + const adapter = new ExpoVideoAdapter(); + + expect(typeof adapter.getAvailabilityInfo).toBe('function'); + + const info = adapter.getAvailabilityInfo(); + expect(info).toHaveProperty('available'); + expect(info).toHaveProperty('installationCommand', 'npx expo install expo-video'); + + if (!info.available) { + expect(info).toHaveProperty('error'); + expect(typeof info.error).toBe('string'); + } + }); + + it('should throw descriptive error when rendering video with unavailable module', () => { + const adapter = new ExpoVideoAdapter(); + + // Only test if expo-video is actually not available (which it likely isn't in test environment) + if (!adapter.isAvailable()) { + const props = { videoUri: 'test://video.mp4' }; + const ref = { current: null }; + + expect(() => { + adapter.renderVideo(props, ref); + }).toThrow(/ExpoVideoAdapter:.*Please install expo-video:/); + } + }); + }); + + describe('FallbackVideoAdapter', () => { + it('should always be available and provide installation guidance', () => { + const adapter = new FallbackVideoAdapter('Custom error message'); + + expect(adapter.isAvailable()).toBe(true); + + const info = adapter.getAvailabilityInfo(); + expect(info).toEqual({ + available: true, + error: 'Custom error message', + installationCommand: 'npx expo install expo-video expo-av' + }); + }); + + it('should use default error message when none provided', () => { + const adapter = new FallbackVideoAdapter(); + + const info = adapter.getAvailabilityInfo(); + expect(info).toEqual({ + available: true, + error: 'No video player available', + installationCommand: 'npx expo install expo-video expo-av' + }); + }); + }); + + describe('Error Message Format', () => { + it('should include adapter name in error messages', () => { + const expoAVAdapter = new ExpoAVVideoAdapter(); + const expoVideoAdapter = new ExpoVideoAdapter(); + + if (!expoAVAdapter.isAvailable()) { + const props = { videoUri: 'test://video.mp4' }; + const ref = { current: null }; + + expect(() => { + expoAVAdapter.renderVideo(props, ref); + }).toThrow(/ExpoAVVideoAdapter:/); + } + + if (!expoVideoAdapter.isAvailable()) { + const props = { videoUri: 'test://video.mp4' }; + const ref = { current: null }; + + expect(() => { + expoVideoAdapter.renderVideo(props, ref); + }).toThrow(/ExpoVideoAdapter:/); + } + }); + + it('should include installation commands in error messages', () => { + const expoAVAdapter = new ExpoAVVideoAdapter(); + const expoVideoAdapter = new ExpoVideoAdapter(); + + if (!expoAVAdapter.isAvailable()) { + const props = { videoUri: 'test://video.mp4' }; + const ref = { current: null }; + + expect(() => { + expoAVAdapter.renderVideo(props, ref); + }).toThrow(/npx expo install expo-av/); + } + + if (!expoVideoAdapter.isAvailable()) { + const props = { videoUri: 'test://video.mp4' }; + const ref = { current: null }; + + expect(() => { + expoVideoAdapter.renderVideo(props, ref); + }).toThrow(/npx expo install expo-video/); + } + }); + }); +}); \ No newline at end of file diff --git a/src/adapters/types.ts b/src/adapters/types.ts index 45abf46..bc46c67 100644 --- a/src/adapters/types.ts +++ b/src/adapters/types.ts @@ -30,6 +30,16 @@ export interface VideoPlayerAdapter { */ getAdapterName(): string; + /** + * Get detailed information about adapter availability + * @returns Object containing availability status, error details, and installation guidance + */ + getAvailabilityInfo?(): { + available: boolean; + error?: string; + installationCommand?: string; + }; + /** * Render the video component */ From 1081439e19504f17502d3206cd01879ba31fc24b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Oct 2025 20:01:16 +0530 Subject: [PATCH 2/2] improve: better error messages and consistent naming --- ENHANCED_ERROR_HANDLING.md | 8 ++--- src/adapters/ExpoAVVideoAdapter.tsx | 28 +++++++++------ src/adapters/ExpoVideoAdapter.tsx | 36 ++++++++++++++------ src/adapters/FallbackVideoAdapter.tsx | 4 +-- src/adapters/__tests__/ErrorHandling.test.ts | 16 ++++----- src/adapters/types.ts | 2 +- 6 files changed, 57 insertions(+), 37 deletions(-) diff --git a/ENHANCED_ERROR_HANDLING.md b/ENHANCED_ERROR_HANDLING.md index 2a3c9d1..a2afeaf 100644 --- a/ENHANCED_ERROR_HANDLING.md +++ b/ENHANCED_ERROR_HANDLING.md @@ -21,7 +21,7 @@ All video adapters now implement an optional `getAvailabilityInfo()` method that ```typescript { - available: boolean; + isAvailable: boolean; error?: string; installationCommand?: string; } @@ -36,7 +36,7 @@ const adapter = VideoPlayerFactory.getAvailableAdapter(); // Check availability with detailed information const info = adapter.getAvailabilityInfo?.(); -if (!info?.available) { +if (!info?.isAvailable) { console.log(`Error: ${info.error}`); console.log(`Install with: ${info.installationCommand}`); } @@ -51,7 +51,7 @@ Error: expo-av is not available ### After (Detailed) ``` -Error: ExpoAVVideoAdapter: Module not found: expo-av. Please install expo-av: "npx expo install expo-av" +Error: ExpoAVVideoAdapter: Module not found: expo-av. Please install: "npx expo install expo-av" ``` ## Benefits @@ -88,7 +88,7 @@ try { // After (enhanced) if (!adapter.isAvailable()) { const info = adapter.getAvailabilityInfo?.(); - if (info && !info.available) { + if (info && !info.isAvailable) { console.error(`Video adapter error: ${info.error}`); console.log(`Fix with: ${info.installationCommand}`); return; diff --git a/src/adapters/ExpoAVVideoAdapter.tsx b/src/adapters/ExpoAVVideoAdapter.tsx index 939d438..6c66e5e 100644 --- a/src/adapters/ExpoAVVideoAdapter.tsx +++ b/src/adapters/ExpoAVVideoAdapter.tsx @@ -3,7 +3,6 @@ import { VideoPlayerAdapter, VideoPlayerProps, VideoPlayerRef, VideoPlayerType } export class ExpoAVVideoAdapter implements VideoPlayerAdapter { private expoAVModule: any = null; - private loadError: Error | null = null; constructor() { this.loadExpoAV(); @@ -13,7 +12,6 @@ export class ExpoAVVideoAdapter implements VideoPlayerAdapter { try { this.expoAVModule = require('expo-av'); } catch (error) { - this.loadError = error as Error; this.expoAVModule = null; } } @@ -27,19 +25,27 @@ export class ExpoAVVideoAdapter implements VideoPlayerAdapter { * @returns Object containing availability status, error details, and installation guidance */ getAvailabilityInfo(): { - available: boolean; + isAvailable: boolean; error?: string; installationCommand?: string; } { - if (this.isAvailable()) { - return { available: true }; + if (!this.expoAVModule) { + return { + isAvailable: false, + error: 'Module not found: expo-av', + installationCommand: 'npx expo install expo-av' + }; } - return { - available: false, - error: this.loadError?.message || 'expo-av not installed', - installationCommand: 'npx expo install expo-av' - }; + if (!this.expoAVModule.Video) { + return { + isAvailable: false, + error: 'Video component not found in expo-av module', + installationCommand: 'npx expo install expo-av' + }; + } + + return { isAvailable: true }; } getAdapterName(): string { @@ -50,7 +56,7 @@ export class ExpoAVVideoAdapter implements VideoPlayerAdapter { if (!this.isAvailable()) { const info = this.getAvailabilityInfo(); throw new Error( - `ExpoAVVideoAdapter: ${info.error}. Please install expo-av: "${info.installationCommand}"` + `ExpoAVVideoAdapter: ${info.error}. Please install: "${info.installationCommand}"` ); } diff --git a/src/adapters/ExpoVideoAdapter.tsx b/src/adapters/ExpoVideoAdapter.tsx index c3e2271..35d472a 100644 --- a/src/adapters/ExpoVideoAdapter.tsx +++ b/src/adapters/ExpoVideoAdapter.tsx @@ -4,7 +4,6 @@ import { VideoPlayerAdapter, VideoPlayerProps, VideoPlayerRef, VideoPlayerType } export class ExpoVideoAdapter implements VideoPlayerAdapter { private expoVideoModule: any = null; private videoPlayer: any = null; - private loadError: Error | null = null; constructor() { this.loadExpoVideo(); @@ -14,7 +13,6 @@ export class ExpoVideoAdapter implements VideoPlayerAdapter { try { this.expoVideoModule = require('expo-video'); } catch (error) { - this.loadError = error as Error; this.expoVideoModule = null; } } @@ -31,19 +29,35 @@ export class ExpoVideoAdapter implements VideoPlayerAdapter { * @returns Object containing availability status, error details, and installation guidance */ getAvailabilityInfo(): { - available: boolean; + isAvailable: boolean; error?: string; installationCommand?: string; } { - if (this.isAvailable()) { - return { available: true }; + if (!this.expoVideoModule) { + return { + isAvailable: false, + error: 'Module not found: expo-video', + installationCommand: 'npx expo install expo-video' + }; } - return { - available: false, - error: this.loadError?.message || 'expo-video not installed', - installationCommand: 'npx expo install expo-video' - }; + if (!this.expoVideoModule.VideoView) { + return { + isAvailable: false, + error: 'VideoView component not found in expo-video module', + installationCommand: 'npx expo install expo-video' + }; + } + + if (!this.expoVideoModule.createVideoPlayer) { + return { + isAvailable: false, + error: 'createVideoPlayer function not found in expo-video module', + installationCommand: 'npx expo install expo-video' + }; + } + + return { isAvailable: true }; } getAdapterName(): string { @@ -54,7 +68,7 @@ export class ExpoVideoAdapter implements VideoPlayerAdapter { if (!this.isAvailable()) { const info = this.getAvailabilityInfo(); throw new Error( - `ExpoVideoAdapter: ${info.error}. Please install expo-video: "${info.installationCommand}"` + `ExpoVideoAdapter: ${info.error}. Please install: "${info.installationCommand}"` ); } diff --git a/src/adapters/FallbackVideoAdapter.tsx b/src/adapters/FallbackVideoAdapter.tsx index 59e1fbe..4b90312 100644 --- a/src/adapters/FallbackVideoAdapter.tsx +++ b/src/adapters/FallbackVideoAdapter.tsx @@ -22,12 +22,12 @@ export class FallbackVideoAdapter implements VideoPlayerAdapter { * @returns Object containing availability status and installation guidance for video libraries */ getAvailabilityInfo(): { - available: boolean; + isAvailable: boolean; error?: string; installationCommand?: string; } { return { - available: true, + isAvailable: true, error: this.errorMessage, installationCommand: 'npx expo install expo-video expo-av' }; diff --git a/src/adapters/__tests__/ErrorHandling.test.ts b/src/adapters/__tests__/ErrorHandling.test.ts index ff171a3..98a508f 100644 --- a/src/adapters/__tests__/ErrorHandling.test.ts +++ b/src/adapters/__tests__/ErrorHandling.test.ts @@ -10,10 +10,10 @@ describe('Video Adapter Error Handling Improvements', () => { expect(typeof adapter.getAvailabilityInfo).toBe('function'); const info = adapter.getAvailabilityInfo(); - expect(info).toHaveProperty('available'); + expect(info).toHaveProperty('isAvailable'); expect(info).toHaveProperty('installationCommand', 'npx expo install expo-av'); - if (!info.available) { + if (!info.isAvailable) { expect(info).toHaveProperty('error'); expect(typeof info.error).toBe('string'); } @@ -29,7 +29,7 @@ describe('Video Adapter Error Handling Improvements', () => { expect(() => { adapter.renderVideo(props, ref); - }).toThrow(/ExpoAVVideoAdapter:.*Please install expo-av:/); + }).toThrow(/ExpoAVVideoAdapter:.*Please install:/); } }); @@ -50,10 +50,10 @@ describe('Video Adapter Error Handling Improvements', () => { expect(typeof adapter.getAvailabilityInfo).toBe('function'); const info = adapter.getAvailabilityInfo(); - expect(info).toHaveProperty('available'); + expect(info).toHaveProperty('isAvailable'); expect(info).toHaveProperty('installationCommand', 'npx expo install expo-video'); - if (!info.available) { + if (!info.isAvailable) { expect(info).toHaveProperty('error'); expect(typeof info.error).toBe('string'); } @@ -69,7 +69,7 @@ describe('Video Adapter Error Handling Improvements', () => { expect(() => { adapter.renderVideo(props, ref); - }).toThrow(/ExpoVideoAdapter:.*Please install expo-video:/); + }).toThrow(/ExpoVideoAdapter:.*Please install:/); } }); }); @@ -82,7 +82,7 @@ describe('Video Adapter Error Handling Improvements', () => { const info = adapter.getAvailabilityInfo(); expect(info).toEqual({ - available: true, + isAvailable: true, error: 'Custom error message', installationCommand: 'npx expo install expo-video expo-av' }); @@ -93,7 +93,7 @@ describe('Video Adapter Error Handling Improvements', () => { const info = adapter.getAvailabilityInfo(); expect(info).toEqual({ - available: true, + isAvailable: true, error: 'No video player available', installationCommand: 'npx expo install expo-video expo-av' }); diff --git a/src/adapters/types.ts b/src/adapters/types.ts index bc46c67..5ee4799 100644 --- a/src/adapters/types.ts +++ b/src/adapters/types.ts @@ -35,7 +35,7 @@ export interface VideoPlayerAdapter { * @returns Object containing availability status, error details, and installation guidance */ getAvailabilityInfo?(): { - available: boolean; + isAvailable: boolean; error?: string; installationCommand?: string; };