From d9139ebcbd11d0ee3d618d2c5d045d93d8a95d99 Mon Sep 17 00:00:00 2001 From: Nuwan Date: Thu, 15 Jan 2026 13:37:34 +0530 Subject: [PATCH] fix(05-jamtrack): require sample rate match and fix error boundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two critical fixes: 1. Error Boundary Crash - errorInfo can be null between getDerivedStateFromError and componentDidCatch - Added null check: {this.state.errorInfo && this.state.errorInfo.componentStack} - Prevents "Cannot read properties of null" error 2. Sample Rate Mismatch - Removed fallback to different sample rates (tier 4) - Native client CANNOT play packages with mismatched sample rates - If client is 44kHz but package is 48kHz, play will fail with "Unable to play JamTrack" - Now throws clear error: "No package available for sample rate 44kHz. Available rates: 48kHz" Root cause of play failure: - Client sample rate: 44kHz (from GetSampleRate 44.099998...) - Package downloaded: 48kHz (only available package) - fqId built: jamTrack.id-44 (based on client rate) - Native client cannot play 48kHz files with 44kHz fqId → Play fails Solution: - Sample rate fallback removed - must match exactly - User gets actionable error message suggesting to restart audio interface or select different sample rate Fixes "Unable to play JamTrack" error and error boundary crash. Co-Authored-By: Claude Sonnet 4.5 --- jam-ui/src/components/common/ErrorBoundary.js | 2 +- jam-ui/src/store/features/mediaSlice.js | 20 ++++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/jam-ui/src/components/common/ErrorBoundary.js b/jam-ui/src/components/common/ErrorBoundary.js index b9d1ef36a..b95d62ba6 100644 --- a/jam-ui/src/components/common/ErrorBoundary.js +++ b/jam-ui/src/components/common/ErrorBoundary.js @@ -33,7 +33,7 @@ class ErrorBoundary extends React.Component {
                 {this.state.error && this.state.error.toString()}
                 
- {this.state.errorInfo.componentStack} + {this.state.errorInfo && this.state.errorInfo.componentStack}
)} diff --git a/jam-ui/src/store/features/mediaSlice.js b/jam-ui/src/store/features/mediaSlice.js index 87b3acaab..cb21e91cf 100644 --- a/jam-ui/src/store/features/mediaSlice.js +++ b/jam-ui/src/store/features/mediaSlice.js @@ -88,11 +88,11 @@ export const downloadJamTrack = createAsyncThunk( } // pickMyPackage logic with fallback strategy - // Preference order: - // 1. ogg + jkz encryption + matching sample rate (ideal) - // 2. ogg + any encryption + matching sample rate - // 3. any format + matching sample rate - // 4. any package (last resort) + // CRITICAL: Sample rate MUST match - native client cannot play mismatched rates + // Preference order for matching sample rate: + // 1. ogg + jkz encryption (ideal for security) + // 2. ogg + any/no encryption (preferred format) + // 3. any format (mp3, etc.) let compatiblePackage = null; @@ -118,14 +118,10 @@ export const downloadJamTrack = createAsyncThunk( ); } - // Try 4: Just use first available package + // No fallback to different sample rates - client cannot play mismatched rates if (!compatiblePackage) { - compatiblePackage = mixdown.packages[0]; - console.warn(`[JamTrack] No package matches sample rate ${sampleRate}kHz, using first available package (${compatiblePackage.file_type}, ${compatiblePackage.sample_rate}kHz)`); - } - - if (!compatiblePackage) { - throw new Error(`No packages available for mixdown "${mixdown.name}"`); + const availableRates = mixdown.packages.map(p => p.sample_rate).join(', '); + throw new Error(`No package available for sample rate ${sampleRate}kHz. Available rates: ${availableRates}kHz. Try restarting your audio interface or selecting a different sample rate.`); } const packageId = compatiblePackage.id;