---
description: Systematic debugging approach for implementation mode issues and common failures
globs: []
alwaysApply: false
---

# Debugging Workflow

When debugging issues in the Mixpanel library, follow this systematic approach:

## Step 1: Determine Implementation Mode (FIRST)

ALWAYS start by identifying which implementation is active:

```javascript
// Add this debug code to any troubleshooting session
const debugImplementationMode = () => {
  console.log('=== Mixpanel Debug Info ===');
  console.log('Native module available:', !!NativeModules.MixpanelReactNative);
  console.log('Implementation type:', 
    mixpanel.mixpanelImpl === MixpanelReactNative ? 'Native' : 'JavaScript');
  console.log('Platform:', Platform.OS);
  console.log('==============================');
};
```

**Why This Matters:**
- Native and JS modes have different failure patterns
- Different debugging approaches required
- Helps identify bridge vs. application logic issues

## Step 2: Enable Comprehensive Logging (REQUIRED)

```javascript
// Enable logging for ALL debugging sessions
mixpanel.setLoggingEnabled(true);

// Verify logging is working
console.log('Logging enabled:', mixpanel.config?.getLoggingEnabled?.(token));

// Look for [Mixpanel] prefix in console
// Expected: [Mixpanel] Track 'Event Name' with properties {...}
```

## Step 3: Check Basic Configuration

```javascript
const debugConfiguration = async () => {
  console.log('=== Configuration Debug ===');
  console.log('Token:', mixpanel.token);
  console.log('Track automatic events:', mixpanel.trackAutomaticEvents);
  console.log('Opted out:', await mixpanel.hasOptedOutTracking());
  console.log('Distinct ID:', await mixpanel.getDistinctId());
  console.log('Device ID:', await mixpanel.getDeviceId());
  console.log('Super properties:', await mixpanel.getSuperProperties());
  console.log('==============================');
};
```

## Native Mode Debugging

### Issue: "MixpanelReactNative is not available"

#### iOS Troubleshooting
```bash
# Clean and reinstall pods
cd ios
pod install --repo-update
cd ..

# Verify Podfile contains correct entry
# Should have: pod 'MixpanelReactNative', :path => '../node_modules/mixpanel-react-native'

# Clean and rebuild
npx react-native run-ios --reset-cache
```

#### Android Troubleshooting
```bash
# Clean and rebuild
cd android
./gradlew clean
./gradlew build
cd ..

# Verify autolinking worked
npx react-native config

# Clean and rebuild
npx react-native run-android --reset-cache
```

### Issue: Native Method Calls Failing

```javascript
// Test native bridge directly
const testNativeBridge = async () => {
  try {
    await NativeModules.MixpanelReactNative?.initialize?.(
      'test-token', 
      true, 
      false, 
      {}, 
      'https://api.mixpanel.com',
      false
    );
    console.log('✅ Native bridge working');
  } catch (error) {
    console.error('❌ Native bridge error:', error);
    console.log('Available methods:', Object.keys(NativeModules.MixpanelReactNative || {}));
  }
};
```

### Platform-Specific Issues

#### iOS-Specific Debugging
```javascript
const debugiOS = () => {
  if (Platform.OS === 'ios') {
    console.log('=== iOS Debug ===');
    
    // Test iOS-specific methods
    try {
      mixpanel.setFlushOnBackground(true);
      console.log('✅ iOS setFlushOnBackground working');
    } catch (error) {
      console.error('❌ iOS method error:', error);
    }
  }
};
```

#### Android-Specific Debugging
```javascript
const debugAndroid = () => {
  if (Platform.OS === 'android') {
    console.log('=== Android Debug ===');
    
    // Note: Android doesn't support setFlushOnBackground
    console.log('Flush on background not supported on Android');
    
    // Check thread synchronization issues
    console.log('Instance management: Thread-safe synchronized');
  }
};
```

## JavaScript Mode Debugging

### Issue: Events Not Being Tracked

```javascript
const debugEventTracking = async () => {
  console.log('=== Event Tracking Debug ===');
  
  // Check opt-out status FIRST
  const optedOut = await mixpanel.hasOptedOutTracking();
  console.log('Opted out:', optedOut);
  
  if (optedOut) {
    console.log('❌ User has opted out - events will not be tracked');
    return;
  }
  
  // Test queue addition
  mixpanel.track('Debug Event', { debug: true, timestamp: Date.now() });
  
  // In JavaScript mode, events should be queued
  if (mixpanel.mixpanelImpl !== MixpanelReactNative) {
    console.log('✅ JavaScript mode - event should be queued');
  }
  
  console.log('=============================');
};
```

### Issue: Queue Not Processing

```javascript
const debugQueueProcessing = () => {
  console.log('=== Queue Processing Debug ===');
  
  // Check flush configuration
  const config = mixpanel.mixpanelImpl?.config;
  if (config) {
    console.log('Flush interval:', config.getFlushInterval?.(mixpanel.token));
    console.log('Batch size:', config.getFlushBatchSize?.(mixpanel.token));
    console.log('Server URL:', config.getServerURL?.(mixpanel.token));
  }
  
  // Manual flush test
  console.log('Triggering manual flush...');
  mixpanel.flush();
  
  console.log('===============================');
};
```

### Issue: Storage Problems

```javascript
const debugStorage = async () => {
  console.log('=== Storage Debug ===');
  
  try {
    // Test AsyncStorage directly
    await AsyncStorage.setItem('mixpanel_test_key', 'test_value');
    const value = await AsyncStorage.getItem('mixpanel_test_key');
    console.log('✅ AsyncStorage working:', value === 'test_value');
    await AsyncStorage.removeItem('mixpanel_test_key');
  } catch (error) {
    console.error('❌ AsyncStorage error:', error);
    console.log('Falling back to in-memory storage');
  }
  
  // Test Mixpanel storage
  try {
    await mixpanel.registerSuperProperties({ debug_test: true });
    const newProps = await mixpanel.getSuperProperties();
    console.log('✅ Mixpanel storage working:', newProps.debug_test === true);
  } catch (error) {
    console.error('❌ Mixpanel storage error:', error);
  }
  
  console.log('===================');
};
```

## Network Debugging

### Test Network Connectivity

```javascript
const debugNetwork = async () => {
  console.log('=== Network Debug ===');
  
  try {
    const response = await fetch('https://api.mixpanel.com/track/', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: 'data=' + encodeURIComponent(JSON.stringify([{
        event: 'Debug Test',
        properties: {
          token: mixpanel.token,
          time: Date.now(),
          distinct_id: 'debug-user'
        }
      }]))
    });
    
    console.log('Network response status:', response.status);
    const result = await response.json();
    console.log('Network response body:', result);
    
    if (response.status === 200 && result === 1) {
      console.log('✅ Network connectivity working');
    } else {
      console.log('❌ Network issue detected');
    }
  } catch (error) {
    console.error('❌ Network error:', error);
  }
  
  console.log('===================');
};
```

### Test Server URL Configuration

```javascript
const debugServerURL = () => {
  console.log('=== Server URL Debug ===');
  
  const config = mixpanel.mixpanelImpl?.config;
  if (config) {
    const serverURL = config.getServerURL?.(mixpanel.token);
    console.log('Current server URL:', serverURL);
    
    // Test valid URLs
    const validURLs = [
      'https://api.mixpanel.com',      // Default
      'https://api-eu.mixpanel.com',   // EU
    ];
    
    validURLs.forEach(url => {
      console.log(`Testing URL: ${url}`);
      try {
        mixpanel.setServerURL(url);
        console.log(`✅ ${url} set successfully`);
      } catch (error) {
        console.error(`❌ ${url} failed:`, error);
      }
    });
  }
  
  console.log('========================');
};
```

## Common Error Scenarios

### Silent Failures

```javascript
const debugSilentFailures = () => {
  console.log('=== Silent Failure Debug ===');
  
  // Test problematic data types that might cause silent failures
  const testCases = [
    { name: 'Circular reference', data: {} },
    { name: 'Function property', data: { fn: () => {} } },
    { name: 'Symbol property', data: { sym: Symbol('test') } },
    { name: 'Large object', data: { large: 'x'.repeat(10000) } },
  ];
  
  // Create circular reference
  testCases[0].data.self = testCases[0].data;
  
  testCases.forEach(testCase => {
    console.log(`Testing: ${testCase.name}`);
    try {
      JSON.stringify(testCase.data);
      console.log(`✅ ${testCase.name} - serializable`);
      
      mixpanel.track(`Test ${testCase.name}`, testCase.data);
      console.log(`✅ ${testCase.name} - tracked successfully`);
    } catch (error) {
      console.error(`❌ ${testCase.name} - error:`, error.message);
    }
  });
  
  console.log('============================');
};
```

### Memory Leaks

```javascript
const debugMemoryUsage = async () => {
  console.log('=== Memory Usage Debug ===');
  
  const initialMemory = performance.memory?.usedJSHeapSize || 'Unknown';
  console.log('Initial memory:', initialMemory);
  
  // Create multiple instances to test cleanup
  const instances = [];
  for (let i = 0; i < 10; i++) {
    const instance = new Mixpanel(`test-token-${i}`, true);
    await instance.init();
    instances.push(instance);
  }
  
  const afterCreateMemory = performance.memory?.usedJSHeapSize || 'Unknown';
  console.log('Memory after creating 10 instances:', afterCreateMemory);
  
  // Reset all instances
  for (const instance of instances) {
    await instance.reset();
  }
  
  const afterResetMemory = performance.memory?.usedJSHeapSize || 'Unknown';
  console.log('Memory after reset:', afterResetMemory);
  
  console.log('==========================');
};
```

### Timing Issues

```javascript
const debugTimingIssues = async () => {
  console.log('=== Timing Issues Debug ===');
  
  // Test rapid initialization
  const startTime = Date.now();
  const instance = new Mixpanel('timing-test-token', true);
  
  // Multiple rapid calls
  const promises = [];
  for (let i = 0; i < 5; i++) {
    promises.push(instance.init());
  }
  
  try {
    await Promise.all(promises);
    const endTime = Date.now();
    console.log(`✅ Multiple init calls completed in ${endTime - startTime}ms`);
  } catch (error) {
    console.error('❌ Timing issue detected:', error);
  }
  
  // Test rapid tracking
  for (let i = 0; i < 100; i++) {
    instance.track(`Rapid Event ${i}`, { index: i });
  }
  
  console.log('✅ Rapid tracking completed');
  console.log('==========================');
};
```

## Complete Health Check

Run this comprehensive diagnostic when debugging any issue:

```javascript
const runCompleteHealthCheck = async () => {
  console.log('🔍 Starting Mixpanel Health Check...\n');
  
  try {
    // 1. Implementation mode
    debugImplementationMode();
    
    // 2. Configuration
    await debugConfiguration();
    
    // 3. Storage
    await debugStorage();
    
    // 4. Network
    await debugNetwork();
    
    // 5. Event tracking
    await debugEventTracking();
    
    // 6. Platform-specific
    if (Platform.OS === 'ios') {
      debugiOS();
    } else if (Platform.OS === 'android') {
      debugAndroid();
    }
    
    console.log('✅ Health check completed');
  } catch (error) {
    console.error('❌ Health check failed:', error);
  }
};
```

## Performance Monitor

```javascript
const monitorPerformance = () => {
  const originalTrack = mixpanel.track.bind(mixpanel);
  let trackCount = 0;
  let totalTime = 0;
  
  mixpanel.track = (eventName, properties) => {
    const startTime = Date.now();
    trackCount++;
    
    const result = originalTrack(eventName, properties);
    
    const endTime = Date.now();
    const duration = endTime - startTime;
    totalTime += duration;
    
    console.log(`Track #${trackCount}: ${eventName} (${duration}ms)`);
    console.log(`Average time per track: ${(totalTime / trackCount).toFixed(2)}ms`);
    
    return result;
  };
  
  console.log('Performance monitoring enabled');
};
```

## Issue Resolution Checklist

### Basic Issues
- [ ] Verify implementation mode (native vs JavaScript)
- [ ] Check logging is enabled
- [ ] Confirm token is valid
- [ ] Verify user hasn't opted out
- [ ] Test basic connectivity

### Native Mode Issues
- [ ] Run `pod install` (iOS) or gradle clean/build (Android)
- [ ] Verify autolinking configuration
- [ ] Check native module availability
- [ ] Test native bridge directly
- [ ] Verify platform-specific features

### JavaScript Mode Issues
- [ ] Check AsyncStorage availability
- [ ] Verify queue processing
- [ ] Test manual flush
- [ ] Check storage persistence
- [ ] Monitor network requests

### Performance Issues
- [ ] Monitor memory usage
- [ ] Check for circular references
- [ ] Verify batch sizes
- [ ] Test under load
- [ ] Check timing/race conditions

### Data Issues
- [ ] Verify event structure
- [ ] Check super properties
- [ ] Test identity management
- [ ] Validate serialization
- [ ] Confirm server responses

Use this debugging workflow systematically to identify and resolve issues across both implementation modes and all major subsystems.