Skip to content

Commit 98aa58c

Browse files
archive(plugin): preserve old native exception handler
- Archive nativeExceptionHandler.cjs as .old for reference - Functionality replaced by unified error handler service
1 parent a60b9ce commit 98aa58c

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// const { withDangerousMod, withMainApplication } = require('@expo/config-plugins');
2+
// const fs = require('fs');
3+
// const path = require('path');
4+
5+
// // Inject native uncaught handler + CrashTester module with verbose debug logging
6+
// module.exports = function withNativeExceptionHandler(config) {
7+
8+
// function resolveAndroidPackage(config) {
9+
// return (
10+
// config?.android?.package ||
11+
// config?.expo?.android?.package ||
12+
// process.env.ANDROID_PACKAGE_NAME ||
13+
// 'com.digitalnomad91.codebuilderadmin'
14+
// );
15+
// }
16+
17+
// // Helper: create crash tester native files if absent
18+
// function ensureCrashTesterFiles(projectRoot, packageName) {
19+
// const packagePath = packageName.replace(/\./g, '/');
20+
// const javaDir = path.join(projectRoot, 'android', 'app', 'src', 'main', 'java', packagePath);
21+
// if (!fs.existsSync(javaDir)) fs.mkdirSync(javaDir, { recursive: true });
22+
// const moduleFile = path.join(javaDir, 'CrashTesterModule.java');
23+
// const packageFile = path.join(javaDir, 'CrashTesterPackage.java');
24+
25+
// const moduleSource = `package ${packageName};\n\nimport com.facebook.react.bridge.ReactApplicationContext;\nimport com.facebook.react.bridge.ReactContextBaseJavaModule;\nimport com.facebook.react.bridge.ReactMethod;\nimport android.util.Log;\nimport android.os.Handler;\nimport android.os.Looper;\n\npublic class CrashTesterModule extends ReactContextBaseJavaModule {\n public CrashTesterModule(ReactApplicationContext context) { super(context); }\n @Override public String getName() { return \"CrashTester\"; }\n\n @ReactMethod public void dumpDefaultHandler() {\n Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler();\n if (h == null) {\n Log.e(\"CrashTester\", \"Default UncaughtExceptionHandler: <null>\");\n } else {\n Log.e(\"CrashTester\", \"Default UncaughtExceptionHandler class: \" + h.getClass().getName());\n Log.e(\"CrashTester\", \"Handler toString(): \" + h.toString());\n }\n }\n\n /** Spawn a new background thread and crash there */\n @ReactMethod public void induceNativeException() {\n Log.d(\"CrashTester\", \"induceNativeException() invoked - spawning crash thread\");\n new Thread(() -> {\n try { Thread.sleep(750); } catch (InterruptedException ignored) {}\n Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler();\n Log.e(\"CrashTester\", \"(crash thread) default handler before throw: \" + (h == null ? \"<null>\" : h.getClass().getName()));\n Log.e(\"CrashTester\", \"About to throw uncaught exception on thread: \" + Thread.currentThread().getName());\n throw new RuntimeException(\"CrashTester: induced uncaught thread exception\");\n }, \"CrashTesterThread\").start();\n }\n\n /** Crash on the MAIN (UI) thread */\n @ReactMethod public void induceMainThreadException() {\n Log.d(\"CrashTester\", \"induceMainThreadException() posting to main looper\");\n new Handler(Looper.getMainLooper()).postDelayed(() -> {\n Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler();\n Log.e(\"CrashTester\", \"(main thread) default handler before throw: \" + (h == null ? \"<null>\" : h.getClass().getName()));\n Log.e(\"CrashTester\", \"Throwing on MAIN thread: \" + Thread.currentThread().getName());\n throw new RuntimeException(\"CrashTester: induced MAIN thread exception\");\n }, 600);\n }\n}\n`;
26+
// fs.writeFileSync(moduleFile, moduleSource);
27+
// console.log('[nativeExceptionHandler] (Re)wrote CrashTesterModule.java');
28+
29+
// const packageSource = `package ${packageName};\n\nimport com.facebook.react.ReactPackage;\nimport com.facebook.react.bridge.NativeModule;\nimport com.facebook.react.bridge.ReactApplicationContext;\nimport com.facebook.react.uimanager.ViewManager;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class CrashTesterPackage implements ReactPackage {\n @Override\n public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); }\n @Override\n public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {\n List<NativeModule> modules = new ArrayList<>();\n modules.add(new CrashTesterModule(reactContext));\n return modules;\n }\n}\n`;
30+
// if (!fs.existsSync(packageFile) || fs.readFileSync(packageFile, 'utf8') !== packageSource) {
31+
// fs.writeFileSync(packageFile, packageSource);
32+
// console.log('[nativeExceptionHandler] (Re)wrote CrashTesterPackage.java');
33+
// }
34+
// }
35+
36+
// // 2. Create crash tester native module files
37+
// config = withDangerousMod(config, ['android', async (cfg) => {
38+
// const pkg = resolveAndroidPackage(cfg);
39+
// console.log('[nativeExceptionHandler] Ensuring CrashTester sources for', pkg);
40+
// ensureCrashTesterFiles(cfg.modRequest.projectRoot, pkg);
41+
// return cfg;
42+
// }]);
43+
44+
// // 3. Register CrashTesterPackage in MainApplication
45+
// config = withMainApplication(config, (cfg) => {
46+
// if (!cfg.modResults || !cfg.modResults.contents) return cfg;
47+
// let contents = cfg.modResults.contents;
48+
// const pkg = resolveAndroidPackage(cfg);
49+
// contents = contents.replace(/\nimport .*CrashTesterPackage.*\s*$/,'');
50+
51+
// if (!contents.includes(`import ${pkg}.CrashTesterPackage`)) {
52+
// const importBlockMatch = contents.match(/(package[\s\S]*?)(import[\s\S]*?)(\nclass\s+MainApplication)/);
53+
// if (importBlockMatch) {
54+
// const [full, pkgSeg, importsSeg, classSeg] = importBlockMatch;
55+
// if (!importsSeg.includes(`import ${pkg}.CrashTesterPackage`)) {
56+
// const newImports = importsSeg.trimEnd() + `\nimport ${pkg}.CrashTesterPackage\n`;
57+
// contents = contents.replace(full, pkgSeg + newImports + classSeg);
58+
// console.log('[nativeExceptionHandler] Added CrashTesterPackage import');
59+
// }
60+
// } else {
61+
// contents = contents.replace(/(package [^\n]+\n)/, `$1import ${pkg}.CrashTesterPackage\n`);
62+
// console.log('[nativeExceptionHandler] Fallback import insertion');
63+
// }
64+
// }
65+
66+
// if (!contents.includes('CrashTesterPackage()')) {
67+
// const javaListRegex = /new PackageList\(this\)\.getPackages\(\);/;
68+
// if (javaListRegex.test(contents) && !contents.includes('new CrashTesterPackage()')) {
69+
// contents = contents.replace(javaListRegex, 'new PackageList(this).getPackages();\n packages.add(new CrashTesterPackage());');
70+
// console.log('[nativeExceptionHandler] Injected into Java PackageList');
71+
// }
72+
// const kotlinListRegex = /(val\s+packages\s*=\s*PackageList\(this\)\.packages)/;
73+
// if (kotlinListRegex.test(contents) && !/packages\.add\(CrashTesterPackage\(\)\)/.test(contents)) {
74+
// contents = contents.replace(kotlinListRegex, '$1\n packages.add(CrashTesterPackage())');
75+
// console.log('[nativeExceptionHandler] Injected into Kotlin packages list');
76+
// }
77+
// const manualArrayRegex = /(List<ReactPackage> packages = new ArrayList<ReactPackage>\(\);[\s\S]*?return packages;)/;
78+
// if (manualArrayRegex.test(contents) && !contents.includes('new CrashTesterPackage()')) {
79+
// contents = contents.replace(manualArrayRegex, (block) => block.replace('return packages;', 'packages.add(new CrashTesterPackage());\n return packages;'));
80+
// console.log('[nativeExceptionHandler] Injected into manual array pattern');
81+
// }
82+
// }
83+
84+
// if (contents.includes('CrashTesterPackage()')) {
85+
// console.log('[nativeExceptionHandler] CrashTesterPackage registration confirmed');
86+
// } else {
87+
// console.warn('[nativeExceptionHandler] Could not confirm CrashTesterPackage registration');
88+
// }
89+
90+
// cfg.modResults.contents = contents;
91+
// return cfg;
92+
// });
93+
94+
// return config;
95+
// };
96+

0 commit comments

Comments
 (0)