-
-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Labels
Description
🐛 Bug
Problem
The application crashes with TypeError: Cannot read properties of undefined (reading 'map') when any layer's API call fails during startup, making the entire app unusable.
Root Cause
In lib/src/Components/Map/hooks/useItems.tsx, the setItemsApi function uses toast.promise without error handling:
const setItemsApi = useCallback(async (layer: LayerProps) => {
addLayer(layer)
const result = await toast.promise(layer.api!.getItems(), {...}) // Throws on error
result.map((item) => { // Crashes: result is undefined when API fails
dispatch({ type: 'ADD', item: { ...item, layer } })
})
setallItemsLoaded(true) // Never executes on error
}, [])When the API fails: toast.promise throws → execution stops → result is undefined → .map() crashes.
Reproducible Scenarios
Scenario 1: Backend Server Error
- Configure backend to return 500 Internal Server Error for
/itemsendpoint - Start the application
- Navigate to map page
- Result: App crashes immediately with
TypeError: Cannot read properties of undefined (reading 'map')
Scenario 2: Network Connectivity Issues
- Start the application
- Disconnect network/WiFi during item loading
- Result: Same crash occurs, app becomes unusable
Scenario 3: Invalid API Configuration
- Configure invalid API endpoint in environment variables
- Start the application
- Result: App crashes on startup, search never works
Scenario 4: Database Connection Issues
- Stop the Directus database container
- Start the frontend application
- Result: App crashes when trying to load layers
Impact
- Complete app crash during backend downtime/network issues
- Search becomes permanently broken (no items loaded)
- Affects 100% of users when backend issues occur
- App stuck in loading state (
allItemsLoadedstaysfalse)
Current Architecture Issues
- Multiple Layer Loading: Each layer calls
setItemsApiindependently - Single Loading Flag:
allItemsLoadedis one boolean for all layers - No Partial Loading: One failed layer breaks entire loading mechanism
- Critical Dependencies: Search and profile features depend on
allItemsLoaded
Comprehensive Solution
Phase 1: Immediate Hotfix
const setItemsApi = useCallback(async (layer: LayerProps) => {
addLayer(layer)
try {
const result = await toast.promise(layer.api!.getItems(), {...})
result.map((item) => {
dispatch({ type: 'ADD', item: { ...item, layer } })
})
} catch (error) {
console.error(`Failed to load ${layer.name}:`, error)
// Don't crash - allow app to continue with partial data
} finally {
setallItemsLoaded(true) // Always set loaded state
}
}, [])Phase 2: Enhanced Error Handling
- Add layer-specific loading state tracking
- Implement graceful degradation for partial data loading
- Provide user feedback for failed layers
- Add retry mechanisms for failed layers
Benefits
- ✅ Prevents app crashes immediately
- ✅ Maintains app functionality with partial data
- ✅ Provides foundation for better error handling
- ✅ No breaking changes to existing components
Testing
- Verify app continues working when backend returns 500 errors
- Test with network connectivity issues
- Confirm search works with partially loaded data
- Validate error toast notifications appear