SoulCache

Troubleshooting

Common issues and solutions

Troubleshooting

Queries Not Updating

Symptom: Query data doesn't update when expected.

Solutions:

  1. Check query key stability:
// Bad: Creates new array each render
useQuery({ queryKey: [userId], queryFn });
 
// Good: Stable reference
const queryKey = useMemo(() => [userId], [userId]);
useQuery({ queryKey, queryFn });
  1. Verify cache invalidation:
await client.invalidateQueries(['users']);
  1. Check observer subscription:
const unsubscribe = client.subscribe(['users'], callback);
// Don't forget to unsubscribe

Memory Leaks

Symptom: Application memory grows over time.

Solutions:

  1. Unsubscribe from queries:
useEffect(() => {
  const unsubscribe = client.subscribe(['users'], callback);
  return unsubscribe;
}, []);
  1. Enable garbage collection:
const client = new QueryClient({
  defaultOptions: {
    gcTime: 5 * 60 * 1000, // 5 minutes
  },
});
  1. Monitor observer count:
const stats = client.getCache().getStats();
console.log('Active entries:', stats.activeEntries);

Network Errors

Symptom: Fetch requests fail repeatedly.

Solutions:

  1. Note that QueryClient does not apply a global retry option in the current release. For retrying mutations, use MutationEntry.mutateWithRetry():
const entry = client.getMutationCache().create({
  mutationId: 'mut-1',
  mutationFn: async (vars) => {
    const res = await fetch('/api/data', { method: 'POST', body: JSON.stringify(vars) });
    return res.json();
  },
});
 
// Retries up to 3 times with 1000ms delay
await entry.mutateWithRetry({ name: 'John' }, 3, 1000);
  1. Implement error handling:
try {
  const data = await client.fetchQuery({
    queryKey: ['users'],
    queryFn: fetchUsers,
  });
} catch (error) {
  console.error('Fetch failed:', error);
}
  1. Use error boundaries in React:
<ErrorBoundary fallback={<Error />}>
  <Users />
</ErrorBoundary>

Type Errors

Symptom: TypeScript compilation errors.

Solutions:

  1. Ensure query keys are typed:
const queryKey = ['users'] as const;
  1. Use generic types:
const data = await client.fetchQuery<User[]>({
  queryKey: ['users'],
  queryFn: fetchUsers,
});
  1. Check import paths:
// Good
import { QueryClient } from '@soulcache/core';
import { useQuery } from '@soulcache/react';
 
// Bad: Don't import from internal paths

Performance Issues

Symptom: Application feels slow.

Solutions:

  1. Reduce unnecessary fetches by invalidating the cache only when data changes:
await client.invalidateQueries(['users']); // marks entries stale
await client.fetchQuery({ queryKey: ['users'], queryFn }); // explicit refetch
  1. Monitor metrics:
const metrics = client.getScheduler().getMetrics();
console.log('Tasks completed:', metrics.totalCompleted);

On this page