An app that crashes or resets to empty state when encountering corrupted or missing persisted data — a realistic scenario after OS updates, storage migrations, or unexpected terminations — forces users into a hard logout or blank screen. CWE-755 (Improper Handling of Exceptional Conditions) applies directly: failing to catch parse errors on startup is a class of unhandled exception that destroys user sessions. ISO 25010:2011 reliability.recoverability requires a defined degradation path when restore fails. The business impact is measurable: every startup crash from a missing try/catch translates to an uninstall.
High because an unguarded state restoration failure converts a routine app relaunch into a crash or silent data reset, directly causing user abandonment.
Wrap all startup storage reads in try/catch and always fall through to a safe default state. Show a splash screen until restoration completes so the UI never renders against partially-loaded state.
import { useEffect, useState } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
export function App() {
const [ready, setReady] = useState(false);
const [restoredState, setRestoredState] = useState(null);
useEffect(() => {
(async () => {
try {
const raw = await AsyncStorage.getItem('appState');
if (raw) setRestoredState(JSON.parse(raw));
} catch {
// Corrupted storage — continue with defaults
} finally {
setReady(true);
}
})();
}, []);
if (!ready) return <SplashScreen />;
return <AppNavigation initialState={restoredState} />;
}
Restore at least two state categories (auth + navigation) and verify the fallback branch by deliberately corrupting storage in a test device run.
ID: mobile-offline-storage.data-persistence.state-restoration
Severity: high
What to look for: Examine the app's initialization logic. Look for code that reads persisted data on app startup and restores it into the app state. Check for error handling in case the stored data is corrupted or missing.
Pass criteria: Count all state restoration calls in app initialization code. App reads persisted data on startup and restores at least 2 state categories (logged-in user, navigation state, form progress) without errors. If storage is empty or corrupted, app handles gracefully with a fallback try/catch block.
Fail criteria: App does not attempt to restore state on startup, or crashes if persisted data is corrupted. No more than 0 unhandled exceptions should be possible during state restoration.
Skip (N/A) when: Never — state restoration is essential for continuity.
Detail on fail: "App does not restore any persisted data on startup. Users start fresh every launch."
Remediation: Use a root-level hook or context to restore state on app initialization:
import { useEffect, useState } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
export function App() {
const [isReady, setIsReady] = useState(false);
const [appState, setAppState] = useState(null);
useEffect(() => {
restoreState();
}, []);
const restoreState = async () => {
try {
const stored = await AsyncStorage.getItem('appState');
if (stored) {
setAppState(JSON.parse(stored));
}
} catch (error) {
console.error('Failed to restore state:', error);
// Continue with default state
} finally {
setIsReady(true);
}
};
if (!isReady) {
return <SplashScreen />;
}
return <AppNavigation initialState={appState} />;
}