Troubleshooting
Common issues and solutions when working with react-native-global-exception-handler.
Installation Issues
iOS Pod Installation Fails
Error:
[!] CocoaPods could not find compatible versions for pod "GlobalExceptionHandler"
Solution:
-
Update CocoaPods:
sudo gem install cocoapods -
Clean and reinstall:
cd ios
rm -rf Pods Podfile.lock
pod deintegrate
pod install
cd ..
Android Build Fails
Error:
Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'
Solution:
-
Ensure your
android/build.gradlehas correct Kotlin version:buildscript {
ext {
kotlinVersion = "1.8.0"
}
} -
Clean gradle cache:
cd android
./gradlew clean
./gradlew cleanBuildCache
cd ..
TurboModule Not Found
Only for React Native New architecture
Error:
TurboModuleRegistry.getEnforcing called for module 'GlobalExceptionHandler' but it is not registered
Solution:
-
Ensure you're using React Native 0.68 or higher
-
Clear metro cache:
- npm
- Yarn
- pnpm
- Bun
npx react-native start --reset-cacheyarn dlx react-native start --reset-cachepnpm dlx react-native start --reset-cachebun x react-native start --reset-cache -
Clean and rebuild:
- npm
- Yarn
- pnpm
- Bun
# iOS
cd ios && rm -rf Pods && pod install && cd ..
npx react-native run-ios
# Android
cd android && ./gradlew clean && cd ..
npx react-native run-android# iOS
cd ios && rm -rf Pods && pod install && cd ..
yarn dlx react-native run-ios
# Android
cd android && ./gradlew clean && cd ..
npx react-native run-android# iOS
cd ios && rm -rf Pods && pod install && cd ..
pnpm dlx react-native run-ios
# Android
cd android && ./gradlew clean && cd ..
npx react-native run-android# iOS
cd ios && rm -rf Pods && pod install && cd ..
bun x react-native run-ios
# Android
cd android && ./gradlew clean && cd ..
npx react-native run-android
Runtime Issues
Handler Not Called in Development
Issue: Exception handler doesn't trigger in development mode.
Solution:
For JavaScript exceptions, enable dev mode:
setJSExceptionHandler((error, isFatal) => {
// Your handler
}, true); // ← Set to true to enable in dev mode
Note: Android native handlers may not work as expected in debug mode due to the way debug builds handle uncaught exceptions.
Native Handler Not Working on Android (Debug)
Issue: Native exception handler doesn't trigger in Android debug builds.
Explanation:
In debug mode, React Native's debug infrastructure may interfere with native exception handling. This is expected behavior.
Solution:
Test native exception handling in release builds:
- npm
- Yarn
- pnpm
- Bun
npx react-native run-android --variant=release
yarn dlx react-native run-android --variant=release
pnpm dlx react-native run-android --variant=release
bun x react-native run-android --variant=release
App Doesn't Restart After Crash
Issue: App shows error but doesn't provide restart functionality.
Solution:
For Android, ensure forceAppToQuit is configured:
setNativeExceptionHandler((errorString) => {
// Handle error
}, {
forceAppToQuit: true // Required for proper cleanup
});
For iOS, you must use a custom error screen as iOS doesn't allow programmatic restart.
When to Use forceAppToQuit: false
Issue: Using navigation libraries like react-native-navigation (Wix), and the app quits unexpectedly on errors.
Why: Some navigation libraries recreate the application stack after errors. If forceAppToQuit is true, the app will quit before the navigation library can handle the error properly.
Solution:
Set forceAppToQuit: false to allow the navigation library to handle the error:
setNativeExceptionHandler((errorString) => {
// Log error for debugging
console.log('Native error:', errorString);
// Send to analytics
reportToAnalytics(errorString);
}, {
forceAppToQuit: false, // Let the navigation library handle recovery
callPreviouslyDefinedHandler: true // Chain with navigation's handler
});
Use cases for forceAppToQuit: false:
- Using react-native-navigation (Wix) or similar navigation libraries
- You have custom recovery logic in native code
- You want to allow the app to attempt recovery instead of forcing quit
Note: In most cases, forceAppToQuit: true (default) is recommended for clean crash handling.
Errors Not Reaching Analytics Service
Issue: Errors are captured but not sent to your analytics service.
Solution:
-
Check network connectivity in error handler
-
Queue errors locally for retry:
import AsyncStorage from '@react-native-async-storage/async-storage';
const queueError = async (error) => {
const queue = await AsyncStorage.getItem('error_queue');
const errors = queue ? JSON.parse(queue) : [];
errors.push(error);
await AsyncStorage.setItem('error_queue', JSON.stringify(errors));
};
setJSExceptionHandler((error, isFatal) => {
queueError({ error, isFatal });
}, true);
Testing Issues
simulateNativeCrash Doesn't Work
Issue: Calling simulateNativeCrash has no effect.
Solution:
-
Ensure you're running on a real device or simulator (not web)
-
Check platform:
import { Platform } from 'react-native';
if (Platform.OS === 'ios' || Platform.OS === 'android') {
simulateNativeCrash('nsexception');
} else {
console.log('Not supported on this platform');
} -
Verify the crash type is valid for your platform
Test Crashes Affect Production
Issue: Accidentally left crash simulation code in production build.
Solution:
Use __DEV__ flag to prevent test code in production:
import { simulateNativeCrash } from 'react-native-global-exception-handler';
if (__DEV__) {
// Only available in dev builds
global.simulateCrash = () => {
simulateNativeCrash('nsexception');
};
}
Performance Issues
App Sluggish After Setting Handler
Issue: App performance degrades after setting exception handlers.
Solution:
Keep handlers lightweight:
// ❌ Bad - Heavy synchronous operation
setJSExceptionHandler((error, isFatal) => {
// Expensive operation
const largeData = processHugeDataset();
sendToServer(largeData);
}, true);
// ✅ Good - Async operation
setJSExceptionHandler((error, isFatal) => {
// Queue for later processing
setTimeout(() => {
sendToServer(error);
}, 0);
}, true);
Memory Leaks from Error Handlers
Issue: Memory usage increases over time.
Solution:
Avoid storing references in closures:
// ❌ Bad - Closure captures large data
let largeData = /* ... */;
setJSExceptionHandler((error, isFatal) => {
console.log(largeData); // Keeps largeData in memory
}, true);
// ✅ Good - No closure captures
setJSExceptionHandler((error, isFatal) => {
// Get fresh data when needed
const data = getCurrentData();
console.log(data);
}, true);
Type Issues (TypeScript)
Type Errors with Handler Functions
Error:
Type '(error: Error, isFatal: boolean) => void' is not assignable to type 'JSExceptionHandler'
Solution:
Import types from the library:
import {
setJSExceptionHandler,
type JSExceptionHandler
} from 'react-native-global-exception-handler';
const handler: JSExceptionHandler = (error, isFatal) => {
console.log(error);
};
setJSExceptionHandler(handler, true);
Options Type Not Recognized
Error:
Property 'forceAppToQuit' does not exist on type '{}'
Solution:
Import ExceptionHandlerOptions type:
import {
setNativeExceptionHandler,
type ExceptionHandlerOptions
} from 'react-native-global-exception-handler';
const options: ExceptionHandlerOptions = {
forceAppToQuit: true,
callPreviouslyDefinedHandler: false
};
setNativeExceptionHandler((errorString) => {
console.log(errorString);
}, options);
Compatibility Issues
React Native Version Mismatch
Error:
The package react-native-global-exception-handler requires React Native 0.68+
Solution:
This library requires React Native 0.68 or higher. If you're using an older version:
-
Upgrade React Native:
- npm
- Yarn
- pnpm
- Bun
npx react-native upgradeyarn dlx react-native upgradepnpm dlx react-native upgradebun x react-native upgrade -
Or use the original library for older versions:
- npm
- Yarn
- pnpm
- Bun
npm install react-native-exception-handleryarn add react-native-exception-handlerpnpm add react-native-exception-handlerbun add react-native-exception-handler
Hermes Not Enabled
Issue: Some features don't work without Hermes engine.
Solution:
Enable Hermes in your app:
iOS (ios/Podfile):
use_react_native!(
:path => config[:reactNativePath],
:hermes_enabled => true
)
Android (android/app/build.gradle):
project.ext.react = [
enableHermes: true
]
Getting More Help
If you're still experiencing issues:
-
Check existing issues: GitHub Issues
-
Create a new issue: Include:
- React Native version
- Platform (iOS/Android)
- Error message
- Minimal reproduction code
-
Enable verbose logging:
setJSExceptionHandler((error, isFatal) => {
console.log('Error details:', {
name: error.name,
message: error.message,
stack: error.stack,
isFatal
});
}, true);
Debug Mode
Enable detailed logging for troubleshooting:
// Add to your index.js
if (__DEV__) {
console.log('Global Exception Handler - Debug Mode');
setJSExceptionHandler((error, isFatal) => {
console.log('=== JS Exception Caught ===');
console.log('Fatal:', isFatal);
console.log('Error:', error);
console.log('Stack:', error.stack);
console.log('==========================');
}, true);
setNativeExceptionHandler((errorString) => {
console.log('=== Native Exception Caught ===');
console.log('Error:', errorString);
console.log('===============================');
});
}
Known Issues & Compatibility
Working with Other Error Handlers
If you have other libraries that set error handlers (e.g., error monitoring SDKs), you may want to chain them together:
import { setJSExceptionHandler, getJSExceptionHandler } from 'react-native-global-exception-handler';
// Save the previous handler (might be from another library)
const previousHandler = getJSExceptionHandler();
setJSExceptionHandler((error, isFatal) => {
// Your custom handling
console.log('Custom handler:', error);
// Call the previous handler if it exists
if (previousHandler) {
previousHandler(error, isFatal);
}
}, true);
For native handlers, use the callPreviouslyDefinedHandler option:
setNativeExceptionHandler((errorString) => {
// Your custom handling
console.log('Custom native handler:', errorString);
}, {
callPreviouslyDefinedHandler: true // Chain with previous handler
});