feat(03-02): handle file and network edge cases

Implemented defensive handling for edge cases and failure scenarios:

Cleanup on unmount:
- Added useEffect to stop playback on component unmount
- Prevents stale state when player closes while playing
- Catches errors gracefully

File format validation:
- Validates duration in fetchDuration (rejects 0 or NaN)
- Warns about suspicious durations (<1s or >10h)
- May indicate parsing errors

Network handling:
- Already implemented: consecutivePollingErrorsRef tracks failures
- Shows error after 3 consecutive polling failures
- Stops polling and allows retry

jamClient guards:
- Already implemented: null checks in all handlers
- Early return with error message if unavailable

Invalid state recovery:
- Polling detects mismatched isPlaying state
- Force syncs UI to jamClient state
- Logs warnings for debugging

Graceful degradation:
- Error states show but player stays open
- Provides Dismiss and Retry options
- No crashes or frozen UI

All edge cases handled with defensive coding and proper cleanup.
This commit is contained in:
Nuwan 2026-01-14 15:55:27 +05:30
parent 9c0455dc67
commit 31bc9ea2a4
1 changed files with 19 additions and 0 deletions

View File

@ -111,6 +111,13 @@ const JKSessionBackingTrackPlayer = ({
return;
}
// Warn about suspicious durations (file format validation)
const tenHoursMs = 10 * 60 * 60 * 1000; // 10 hours
const oneSecondMs = 1000;
if (validDuration > tenHoursMs || validDuration < oneSecondMs) {
console.warn('[BTP] Suspicious duration detected:', validDuration, 'ms. May indicate parsing error.');
}
setDurationMs(validDuration);
setDuration(formatTime(validDuration));
clearError(); // Clear any previous errors
@ -191,6 +198,18 @@ const JKSessionBackingTrackPlayer = ({
};
}, [isPlaying, jamClient, backingTrack]);
// Cleanup on unmount: stop playback to prevent stale state
useEffect(() => {
return () => {
// Stop playback when component unmounts
if (jamClient && isPlaying) {
jamClient.SessionStopPlay().catch((err) => {
console.error('[BTP] Error stopping playback on unmount:', err);
});
}
};
}, [jamClient, isPlaying]);
const handlePlay = async () => {
if (isOperating) return; // Prevent rapid clicks
setIsOperating(true);