# Fix Applied: Query Data Cannot Be Undefined ## Summary Successfully fixed the TanStack Query error: **"Query data cannot be undefined. Please make sure to return a value other than undefined from your query function."** ## Root Causes 1. **Missing `gcTime` parameter** in TanStack Query configuration 2. **No response validation** when proxy API returns invalid/missing data 3. **Incorrect generic type constraint** in `FontVirtualList.svelte` ## Changes Applied ### 1. Fixed TanStack Query Configuration **File**: `src/entities/Font/model/store/baseFontStore.svelte.ts` Added `gcTime` parameter to properly manage cached data lifecycle: ```typescript private getOptions(params = this.params): QueryObserverOptions { return { queryKey: this.getQueryKey(params), queryFn: () => this.fetchFn(params), staleTime:5 * 60 *1000, // 5 minutes gcTime: 10 * 60 * 1000, // 10 minutes ✅ ADDED }; } ``` **Impact**: - Prevents stale data from persisting too long - Explicit control over garbage collection timing - Better memory management ### 2. Added Response Validation **File**: `src/entities/Font/model/store/unifiedFontStore.svelte.ts` Added comprehensive validation in `fetchFn`: ```typescript protected async fetchFn(params: ProxyFontsParams): Promise { const response = await fetchProxyFonts(params); // Validate response exists if (!response) { console.error('[UnifiedFontStore] fetchProxyFonts returned undefined', { params }); throw new Error('Proxy API returned undefined response'); } // Validate fonts array exists if (!response.fonts) { console.error('[UnifiedFontStore] response.fonts is undefined', { response }); throw new Error('Proxy API response missing fonts array'); } // Validate fonts is an array if (!Array.isArray(response.fonts)) { console.error('[UnifiedFontStore] response.fonts is not an array', { fonts: response.fonts }); throw new Error('Proxy API fonts is not an array'); } // Store pagination metadata separately for derived values this.#paginationMetadata = { total: response.total ?? 0, limit: response.limit ?? this.params.limit ?? 50, offset: response.offset ?? this.params.offset ?? 0, }; return response.fonts; } ``` **Impact**: - Early detection of invalid API responses - Detailed error logging for debugging - Prevents undefined data from being cached - Fallback to default values for pagination metadata ### 3. Added Fallback to Fontshare API **File**: `src/entities/Font/api/proxy/proxyFonts.ts` Implemented automatic fallback to Fontshare API when proxy fails: ```typescript /** * Whether to use proxy API (true) or fallback (false) * * Set to true when your proxy API is ready: * const USE_PROXY_API = true; * * Set to false to use Fontshare API as fallback during development: * const USE_PROXY_API = false; * * The app will automatically fall back to Fontshare API if the proxy fails. */ const USE_PROXY_API = true; export async function fetchProxyFonts( params: ProxyFontsParams = {}, ): Promise { // Try proxy API first if enabled if (USE_PROXY_API) { try { const queryString = buildQueryString(params); const url = `${PROXY_API_URL}${queryString}`; console.log('[fetchProxyFonts] Fetching from proxy API', { params, url }); const response = await api.get(url); // Validate response has fonts array if (!response.data || !Array.isArray(response.data.fonts)) { console.error('[fetchProxyFonts] Invalid response from proxy API', response.data); throw new Error('Proxy API returned invalid response'); } console.log('[fetchProxyFonts] Proxy API success', { count: response.data.fonts.length, }); return response.data; } catch (error) { console.warn('[fetchProxyFonts] Proxy API failed, using fallback', error); // Check if it's a network error or proxy not available const isNetworkError = error instanceof Error && (error.message.includes('Failed to fetch') || error.message.includes('Network') || error.message.includes('404') || error.message.includes('500')); if (isNetworkError) { // Fall back to Fontshare API console.log('[fetchProxyFonts] Using Fontshare API as fallback'); return await fetchFontshareFallback(params); } // Re-throw other errors if (error instanceof Error) { throw error; } throw new Error(`Failed to fetch fonts from proxy API: ${String(error)}`); } } // Use Fontshare API directly console.log('[fetchProxyFonts] Using Fontshare API (proxy disabled)'); return await fetchFontshareFallback(params); } /** * Fallback to Fontshare API when proxy is unavailable */ async function fetchFontshareFallback( params: ProxyFontsParams, ): Promise { // Import dynamically to avoid circular dependency const { fetchFontshareFonts } = await import('../fontshare/fontshare'); const { normalizeFontshareFonts } = await import('../../lib/normalize/normalize'); // Map proxy params to Fontshare params const fontshareParams = { q: params.q, categories: params.category ? [params.category] : undefined, page: params.offset ? Math.floor(params.offset / (params.limit || 50)) + 1 : undefined, limit: params.limit, }; const response = await fetchFontshareFonts(fontshareParams); const normalizedFonts = normalizeFontshareFonts(response.fonts); return { fonts: normalizedFonts, total: response.count_total, limit: params.limit || response.count, offset: params.offset || 0, }; } ``` **Impact**: - App continues working even if proxy API is down - Allows development without breaking functionality - Automatic detection of network errors - Seamless fallback with console logging ### 4. Fixed Type Constraints **File**: `src/entities/Font/ui/FontVirtualList/FontVirtualList.svelte` Fixed incorrect generic type constraint: **Before**: ```typescript