@grafana/faro-react-native 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/android/build.gradle +118 -36
  2. package/android/consumer-proguard-rules.pro +2 -0
  3. package/android/src/main/java/com/grafana/faro/reactnative/ANRTracker.kt +61 -9
  4. package/android/src/main/java/com/grafana/faro/reactnative/AnrThreadDumpParser.kt +70 -0
  5. package/android/src/main/java/com/grafana/faro/reactnative/ApplicationExitTraceReader.kt +142 -0
  6. package/android/src/main/java/com/grafana/faro/reactnative/FaroAnrCache.kt +163 -0
  7. package/android/src/main/java/com/grafana/faro/reactnative/FaroAnrReporter.kt +163 -0
  8. package/android/src/main/java/com/grafana/faro/reactnative/FaroCrashReporter.kt +243 -50
  9. package/android/src/main/java/com/grafana/faro/reactnative/FaroCrashTraceCache.kt +75 -0
  10. package/android/src/main/java/com/grafana/faro/reactnative/FaroNativeCrashTrace.kt +39 -0
  11. package/android/src/main/java/com/grafana/faro/reactnative/FaroReactNativeModule.kt +99 -8
  12. package/android/src/main/java/com/grafana/faro/reactnative/FaroReactNativePackage.kt +1 -0
  13. package/android/src/main/java/com/grafana/faro/reactnative/FaroUncaughtExceptionHandler.kt +62 -0
  14. package/android/src/main/java/com/grafana/faro/reactnative/TombstoneBacktraceFormatter.kt +117 -0
  15. package/android/src/main/java/com/grafana/faro/reactnative/TombstoneModels.kt +35 -0
  16. package/android/src/main/java/com/grafana/faro/reactnative/TombstoneWireParser.kt +235 -0
  17. package/android/src/main/proto/tombstone.proto +62 -0
  18. package/android/src/test/java/com/grafana/faro/reactnative/AnrStackFiltersTest.kt +28 -0
  19. package/android/src/test/java/com/grafana/faro/reactnative/AnrThreadDumpParserTest.kt +38 -0
  20. package/android/src/test/java/com/grafana/faro/reactnative/FaroAnrCacheTest.kt +81 -0
  21. package/android/src/test/java/com/grafana/faro/reactnative/TombstoneWireParserTest.kt +51 -0
  22. package/dist/cjs/config/getRNInstrumentations.js +3 -1
  23. package/dist/cjs/config/getRNInstrumentations.js.map +1 -1
  24. package/dist/cjs/config/makeRNConfig.js +48 -9
  25. package/dist/cjs/config/makeRNConfig.js.map +1 -1
  26. package/dist/cjs/config/types.js.map +1 -1
  27. package/dist/cjs/generated/faroRNPackageMeta.js +1 -1
  28. package/dist/cjs/generated/faroRNPackageMeta.js.map +1 -1
  29. package/dist/cjs/index.js +3 -2
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/cjs/initialize.js +14 -8
  32. package/dist/cjs/initialize.js.map +1 -1
  33. package/dist/cjs/instrumentations/anr/anrStack.js +19 -0
  34. package/dist/cjs/instrumentations/anr/anrStack.js.map +1 -0
  35. package/dist/cjs/instrumentations/anr/instrumentation.js +374 -72
  36. package/dist/cjs/instrumentations/anr/instrumentation.js.map +1 -1
  37. package/dist/cjs/instrumentations/anr/types.js.map +1 -1
  38. package/dist/cjs/instrumentations/console/index.js +5 -1
  39. package/dist/cjs/instrumentations/console/index.js.map +1 -1
  40. package/dist/cjs/instrumentations/crashReporting/{instrumentation.js → BaseCrashReportingInstrumentation.js} +110 -103
  41. package/dist/cjs/instrumentations/crashReporting/BaseCrashReportingInstrumentation.js.map +1 -0
  42. package/dist/cjs/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.js +41 -0
  43. package/dist/cjs/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.js.map +1 -0
  44. package/dist/cjs/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js +87 -0
  45. package/dist/cjs/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js.map +1 -0
  46. package/dist/cjs/instrumentations/crashReporting/android/crashErrorMessage.js +123 -0
  47. package/dist/cjs/instrumentations/crashReporting/android/crashErrorMessage.js.map +1 -0
  48. package/dist/cjs/instrumentations/crashReporting/android/index.js +12 -0
  49. package/dist/cjs/instrumentations/crashReporting/android/index.js.map +1 -0
  50. package/dist/cjs/instrumentations/crashReporting/android/nativeTombstoneTrace.js +11 -0
  51. package/dist/cjs/instrumentations/crashReporting/android/nativeTombstoneTrace.js.map +1 -0
  52. package/dist/cjs/instrumentations/crashReporting/android/parseAndroidCrashTrace.js +181 -0
  53. package/dist/cjs/instrumentations/crashReporting/android/parseAndroidCrashTrace.js.map +1 -0
  54. package/dist/cjs/instrumentations/crashReporting/index.js +35 -2
  55. package/dist/cjs/instrumentations/crashReporting/index.js.map +1 -1
  56. package/dist/cjs/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js +78 -0
  57. package/dist/cjs/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js.map +1 -0
  58. package/dist/cjs/instrumentations/crashReporting/ios/crashErrorMessage.js +103 -0
  59. package/dist/cjs/instrumentations/crashReporting/ios/crashErrorMessage.js.map +1 -0
  60. package/dist/cjs/instrumentations/crashReporting/ios/index.js +11 -0
  61. package/dist/cjs/instrumentations/crashReporting/ios/index.js.map +1 -0
  62. package/dist/cjs/instrumentations/crashReporting/ios/parseIosCrashTrace.js +48 -0
  63. package/dist/cjs/instrumentations/crashReporting/ios/parseIosCrashTrace.js.map +1 -0
  64. package/dist/cjs/instrumentations/crashReporting/types.js.map +1 -1
  65. package/dist/cjs/instrumentations/errors/index.js +2 -1
  66. package/dist/cjs/instrumentations/errors/index.js.map +1 -1
  67. package/dist/cjs/instrumentations/session/installationId.js +91 -0
  68. package/dist/cjs/instrumentations/session/installationId.js.map +1 -0
  69. package/dist/cjs/instrumentations/session/sessionAttributes.js +152 -89
  70. package/dist/cjs/instrumentations/session/sessionAttributes.js.map +1 -1
  71. package/dist/cjs/metas/appBuildIdentity.js +95 -0
  72. package/dist/cjs/metas/appBuildIdentity.js.map +1 -0
  73. package/dist/cjs/testUtils/mockDeviceInfo.js +5 -0
  74. package/dist/cjs/testUtils/mockDeviceInfo.js.map +1 -1
  75. package/dist/cjs/testUtils/setupTests.js +7 -0
  76. package/dist/cjs/testUtils/setupTests.js.map +1 -1
  77. package/dist/esm/config/getRNInstrumentations.js +3 -1
  78. package/dist/esm/config/getRNInstrumentations.js.map +1 -1
  79. package/dist/esm/config/makeRNConfig.js +49 -10
  80. package/dist/esm/config/makeRNConfig.js.map +1 -1
  81. package/dist/esm/config/types.js.map +1 -1
  82. package/dist/esm/generated/faroRNPackageMeta.js +1 -1
  83. package/dist/esm/generated/faroRNPackageMeta.js.map +1 -1
  84. package/dist/esm/index.js +1 -1
  85. package/dist/esm/index.js.map +1 -1
  86. package/dist/esm/initialize.js +11 -5
  87. package/dist/esm/initialize.js.map +1 -1
  88. package/dist/esm/instrumentations/anr/anrStack.js +16 -0
  89. package/dist/esm/instrumentations/anr/anrStack.js.map +1 -0
  90. package/dist/esm/instrumentations/anr/instrumentation.js +260 -67
  91. package/dist/esm/instrumentations/anr/instrumentation.js.map +1 -1
  92. package/dist/esm/instrumentations/anr/types.js.map +1 -1
  93. package/dist/esm/instrumentations/console/index.js +5 -1
  94. package/dist/esm/instrumentations/console/index.js.map +1 -1
  95. package/dist/esm/instrumentations/crashReporting/{instrumentation.js → BaseCrashReportingInstrumentation.js} +76 -94
  96. package/dist/esm/instrumentations/crashReporting/BaseCrashReportingInstrumentation.js.map +1 -0
  97. package/dist/esm/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.js +18 -0
  98. package/dist/esm/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.js.map +1 -0
  99. package/dist/esm/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js +56 -0
  100. package/dist/esm/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.js.map +1 -0
  101. package/dist/esm/instrumentations/crashReporting/android/crashErrorMessage.js +116 -0
  102. package/dist/esm/instrumentations/crashReporting/android/crashErrorMessage.js.map +1 -0
  103. package/dist/esm/instrumentations/crashReporting/android/index.js +4 -0
  104. package/dist/esm/instrumentations/crashReporting/android/index.js.map +1 -0
  105. package/dist/esm/instrumentations/crashReporting/android/nativeTombstoneTrace.js +8 -0
  106. package/dist/esm/instrumentations/crashReporting/android/nativeTombstoneTrace.js.map +1 -0
  107. package/dist/esm/instrumentations/crashReporting/android/parseAndroidCrashTrace.js +174 -0
  108. package/dist/esm/instrumentations/crashReporting/android/parseAndroidCrashTrace.js.map +1 -0
  109. package/dist/esm/instrumentations/crashReporting/index.js +35 -1
  110. package/dist/esm/instrumentations/crashReporting/index.js.map +1 -1
  111. package/dist/esm/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js +56 -0
  112. package/dist/esm/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.js.map +1 -0
  113. package/dist/esm/instrumentations/crashReporting/ios/crashErrorMessage.js +98 -0
  114. package/dist/esm/instrumentations/crashReporting/ios/crashErrorMessage.js.map +1 -0
  115. package/dist/esm/instrumentations/crashReporting/ios/index.js +4 -0
  116. package/dist/esm/instrumentations/crashReporting/ios/index.js.map +1 -0
  117. package/dist/esm/instrumentations/crashReporting/ios/parseIosCrashTrace.js +44 -0
  118. package/dist/esm/instrumentations/crashReporting/ios/parseIosCrashTrace.js.map +1 -0
  119. package/dist/esm/instrumentations/crashReporting/types.js.map +1 -1
  120. package/dist/esm/instrumentations/errors/index.js +2 -1
  121. package/dist/esm/instrumentations/errors/index.js.map +1 -1
  122. package/dist/esm/instrumentations/session/installationId.js +48 -0
  123. package/dist/esm/instrumentations/session/installationId.js.map +1 -0
  124. package/dist/esm/instrumentations/session/sessionAttributes.js +83 -38
  125. package/dist/esm/instrumentations/session/sessionAttributes.js.map +1 -1
  126. package/dist/esm/metas/appBuildIdentity.js +56 -0
  127. package/dist/esm/metas/appBuildIdentity.js.map +1 -0
  128. package/dist/esm/testUtils/mockDeviceInfo.js +5 -0
  129. package/dist/esm/testUtils/mockDeviceInfo.js.map +1 -1
  130. package/dist/esm/testUtils/setupTests.js +7 -0
  131. package/dist/esm/testUtils/setupTests.js.map +1 -1
  132. package/dist/types/config/makeRNConfig.d.ts +4 -3
  133. package/dist/types/config/types.d.ts +2 -1
  134. package/dist/types/generated/faroRNPackageMeta.d.ts +1 -1
  135. package/dist/types/index.d.ts +2 -2
  136. package/dist/types/initialize.d.ts +4 -2
  137. package/dist/types/instrumentations/anr/anrStack.d.ts +7 -0
  138. package/dist/types/instrumentations/anr/instrumentation.d.ts +23 -28
  139. package/dist/types/instrumentations/anr/types.d.ts +5 -1
  140. package/dist/types/instrumentations/appState/index.d.ts +1 -1
  141. package/dist/types/instrumentations/console/index.d.ts +1 -1
  142. package/dist/types/instrumentations/crashReporting/BaseCrashReportingInstrumentation.d.ts +56 -0
  143. package/dist/types/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.d.ts +12 -0
  144. package/dist/types/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.d.ts +26 -0
  145. package/dist/types/instrumentations/crashReporting/android/crashErrorMessage.d.ts +23 -0
  146. package/dist/types/instrumentations/crashReporting/android/index.d.ts +4 -0
  147. package/dist/types/instrumentations/crashReporting/android/nativeTombstoneTrace.d.ts +2 -0
  148. package/dist/types/instrumentations/crashReporting/android/parseAndroidCrashTrace.d.ts +45 -0
  149. package/dist/types/instrumentations/crashReporting/index.d.ts +25 -2
  150. package/dist/types/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.d.ts +28 -0
  151. package/dist/types/instrumentations/crashReporting/ios/crashErrorMessage.d.ts +14 -0
  152. package/dist/types/instrumentations/crashReporting/ios/index.d.ts +4 -0
  153. package/dist/types/instrumentations/crashReporting/ios/parseIosCrashTrace.d.ts +38 -0
  154. package/dist/types/instrumentations/crashReporting/types.d.ts +18 -51
  155. package/dist/types/instrumentations/frameMonitoring/instrumentation.d.ts +1 -1
  156. package/dist/types/instrumentations/http/index.d.ts +1 -1
  157. package/dist/types/instrumentations/performance/index.d.ts +1 -1
  158. package/dist/types/instrumentations/session/index.d.ts +1 -1
  159. package/dist/types/instrumentations/session/installationId.d.ts +1 -0
  160. package/dist/types/instrumentations/session/sessionAttributes.d.ts +13 -4
  161. package/dist/types/instrumentations/startup/index.d.ts +1 -1
  162. package/dist/types/instrumentations/userActions/index.d.ts +1 -1
  163. package/dist/types/instrumentations/view/index.d.ts +1 -1
  164. package/dist/types/instrumentations/xhr/index.d.ts +1 -1
  165. package/dist/types/metas/appBuildIdentity.d.ts +16 -0
  166. package/dist/types/testUtils/mockFaroReactNativeTracing.d.ts +1 -1
  167. package/dist/types/transports/console/transport.d.ts +1 -1
  168. package/dist/types/transports/fetch/transport.d.ts +1 -1
  169. package/dist/types/transports/offline/transport.d.ts +1 -1
  170. package/ios/faro-upload-composed-source-map.sh +8 -2
  171. package/package.json +5 -5
  172. package/src/config/getRNInstrumentations.ts +5 -1
  173. package/src/config/makeRNConfig.test.ts +59 -3
  174. package/src/config/makeRNConfig.ts +48 -9
  175. package/src/config/types.ts +2 -1
  176. package/src/generated/faroRNPackageMeta.ts +1 -1
  177. package/src/index.ts +2 -1
  178. package/src/initialize.test.ts +71 -15
  179. package/src/initialize.ts +11 -5
  180. package/src/instrumentations/anr/anrStack.test.ts +27 -0
  181. package/src/instrumentations/anr/anrStack.ts +19 -0
  182. package/src/instrumentations/anr/instrumentation.test.ts +45 -0
  183. package/src/instrumentations/anr/instrumentation.ts +301 -67
  184. package/src/instrumentations/anr/types.ts +7 -1
  185. package/src/instrumentations/console/index.ts +5 -1
  186. package/src/instrumentations/console/instrumentation.test.ts +5 -0
  187. package/src/instrumentations/crashReporting/{instrumentation.ts → BaseCrashReportingInstrumentation.ts} +119 -93
  188. package/src/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.ts +23 -0
  189. package/src/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.ts +62 -0
  190. package/src/instrumentations/crashReporting/android/crashErrorMessage.test.ts +182 -0
  191. package/src/instrumentations/crashReporting/android/crashErrorMessage.ts +135 -0
  192. package/src/instrumentations/crashReporting/android/index.ts +4 -0
  193. package/src/instrumentations/crashReporting/android/nativeTombstoneTrace.test.ts +19 -0
  194. package/src/instrumentations/crashReporting/android/nativeTombstoneTrace.ts +8 -0
  195. package/src/instrumentations/crashReporting/android/parseAndroidCrashTrace.test.ts +232 -0
  196. package/src/instrumentations/crashReporting/android/parseAndroidCrashTrace.ts +235 -0
  197. package/src/instrumentations/crashReporting/index.ts +43 -2
  198. package/src/instrumentations/crashReporting/instrumentation.test.ts +42 -0
  199. package/src/instrumentations/crashReporting/ios/IosCrashReportingInstrumentation.ts +62 -0
  200. package/src/instrumentations/crashReporting/ios/crashErrorMessage.test.ts +170 -0
  201. package/src/instrumentations/crashReporting/ios/crashErrorMessage.ts +111 -0
  202. package/src/instrumentations/crashReporting/ios/index.ts +4 -0
  203. package/src/instrumentations/crashReporting/ios/parseIosCrashTrace.test.ts +86 -0
  204. package/src/instrumentations/crashReporting/ios/parseIosCrashTrace.ts +83 -0
  205. package/src/instrumentations/crashReporting/types.ts +19 -58
  206. package/src/instrumentations/errors/index.ts +2 -1
  207. package/src/instrumentations/errors/instrumentation.test.ts +8 -2
  208. package/src/instrumentations/errors/stackTraceParser.test.ts +1 -1
  209. package/src/instrumentations/session/installationId.ts +43 -0
  210. package/src/instrumentations/session/sessionAttributes.test.ts +260 -30
  211. package/src/instrumentations/session/sessionAttributes.ts +112 -22
  212. package/src/metas/appBuildIdentity.test.ts +48 -0
  213. package/src/metas/appBuildIdentity.ts +50 -0
  214. package/src/testUtils/mockDeviceInfo.ts +5 -0
  215. package/src/testUtils/setupTests.ts +7 -0
  216. package/dist/cjs/instrumentations/crashReporting/instrumentation.js.map +0 -1
  217. package/dist/esm/instrumentations/crashReporting/instrumentation.js.map +0 -1
  218. package/dist/types/instrumentations/crashReporting/instrumentation.d.ts +0 -58
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/instrumentations/console/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { allLogLevels, BaseInstrumentation, defaultErrorArgsSerializer, LogLevel, VERSION } from '@grafana/faro-core';\nimport type { LogArgsSerializer } from '@grafana/faro-core';\n\nimport { ErrorMechanism } from '../errors/const';\n\nimport { getDetailsFromConsoleErrorArgs, reactNativeLogArgsSerializer } from './utils';\n\n/**\n * Console instrumentation for React Native\n * Captures console logs and errors\n *\n * Features:\n * - Configurable log levels\n * - Advanced error serialization\n * - Option to treat console.error as log or error\n * - Unpatch support for cleanup\n */\nexport class ConsoleInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-react-native:instrumentation-console';\n readonly version = VERSION;\n\n static defaultDisabledLevels: LogLevel[] = [LogLevel.DEBUG, LogLevel.TRACE, LogLevel.LOG];\n static consoleErrorPrefix = 'console.error: ';\n\n private originalConsole: Partial<Console> = {};\n private errorSerializer: LogArgsSerializer = reactNativeLogArgsSerializer;\n private patchedLevels: LogLevel[] = [];\n private isProcessing = false;\n\n initialize(): void {\n const instrumentationOptions = this.config.consoleInstrumentation;\n\n // Configure error serialization\n const serializeErrors = instrumentationOptions?.serializeErrors || !!instrumentationOptions?.errorSerializer;\n this.errorSerializer = serializeErrors\n ? (instrumentationOptions?.errorSerializer ?? defaultErrorArgsSerializer)\n : reactNativeLogArgsSerializer;\n\n // Store original console methods - use unpatchedConsole from config if available\n // to avoid capturing React Native's patched console (LogBox, DevTools)\n const sourceConsole = this.config.unpatchedConsole ?? console;\n allLogLevels.forEach((level) => {\n this.originalConsole[level] = sourceConsole[level];\n });\n\n // Determine which levels to patch\n this.patchedLevels = allLogLevels.filter(\n (level) =>\n !(instrumentationOptions?.disabledLevels ?? ConsoleInstrumentation.defaultDisabledLevels).includes(level)\n );\n\n // Patch console methods\n this.patchedLevels.forEach((level) => {\n console[level] = (...args: unknown[]) => {\n // Prevent re-entry to avoid infinite loops\n if (this.isProcessing) {\n this.originalConsole[level]?.(...args);\n return;\n }\n\n this.isProcessing = true;\n try {\n if (level === LogLevel.ERROR && !instrumentationOptions?.consoleErrorAsLog) {\n // Handle console.error as an error with advanced serialization\n const { value, type, stackFrames } = getDetailsFromConsoleErrorArgs(args, this.errorSerializer);\n\n const context = { mechanism: ErrorMechanism.CONSOLE };\n\n if (value && !type && !stackFrames) {\n // Simple error without stack frames\n this.api.pushError(new Error(ConsoleInstrumentation.consoleErrorPrefix + value), { context });\n } else {\n // Error with type and/or stack frames (type from error.name, matches Web SDK)\n this.api.pushError(new Error(ConsoleInstrumentation.consoleErrorPrefix + (value ?? '')), {\n context,\n type,\n stackFrames,\n });\n }\n } else if (level === LogLevel.ERROR && instrumentationOptions?.consoleErrorAsLog) {\n // Handle console.error as a log with error details in context\n const { value, type, stackFrames } = getDetailsFromConsoleErrorArgs(args, this.errorSerializer);\n\n this.api.pushLog(value ? [ConsoleInstrumentation.consoleErrorPrefix + value] : args, {\n level,\n context: {\n value: value ?? '',\n type: type ?? '',\n stackFrames: stackFrames?.length ? defaultErrorArgsSerializer(stackFrames) : '',\n },\n });\n } else {\n // Handle other log levels normally\n this.api.pushLog(args, { level });\n }\n } catch (_err) {\n // Silently ignore errors to prevent infinite loops during bootstrap\n } finally {\n // Always call original console method (still protected by isProcessing flag)\n this.originalConsole[level]?.(...args);\n this.isProcessing = false;\n }\n };\n });\n }\n\n /**\n * Restore original console methods\n * Call this to clean up and unpatch the console\n */\n unpatch(): void {\n this.patchedLevels.forEach((level) => {\n if (this.originalConsole[level]) {\n console[level] = this.originalConsole[level];\n }\n });\n\n this.patchedLevels = [];\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/instrumentations/console/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { allLogLevels, BaseInstrumentation, defaultErrorArgsSerializer, LogLevel, VERSION } from '@grafana/faro-core';\nimport type { LogArgsSerializer } from '@grafana/faro-core';\n\nimport { ErrorMechanism } from '../errors/const';\n\nimport { getDetailsFromConsoleErrorArgs, reactNativeLogArgsSerializer } from './utils';\n\n/**\n * Console instrumentation for React Native\n * Captures console logs and errors\n *\n * Features:\n * - Configurable log levels\n * - Advanced error serialization\n * - Option to treat console.error as log or error\n * - Unpatch support for cleanup\n */\nexport class ConsoleInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-react-native:instrumentation-console';\n readonly version = VERSION;\n\n static defaultDisabledLevels: LogLevel[] = [LogLevel.DEBUG, LogLevel.TRACE, LogLevel.LOG];\n static consoleErrorPrefix = 'console.error: ';\n\n private originalConsole: Partial<Console> = {};\n private errorSerializer: LogArgsSerializer = reactNativeLogArgsSerializer;\n private patchedLevels: LogLevel[] = [];\n private isProcessing = false;\n\n initialize(): void {\n const instrumentationOptions = this.config.consoleInstrumentation;\n\n // Configure error serialization\n const serializeErrors = instrumentationOptions?.serializeErrors || !!instrumentationOptions?.errorSerializer;\n this.errorSerializer = serializeErrors\n ? (instrumentationOptions?.errorSerializer ?? defaultErrorArgsSerializer)\n : reactNativeLogArgsSerializer;\n\n // Store original console methods - use unpatchedConsole from config if available\n // to avoid capturing React Native's patched console (LogBox, DevTools)\n const sourceConsole = this.config.unpatchedConsole ?? console;\n allLogLevels.forEach((level) => {\n this.originalConsole[level] = sourceConsole[level];\n });\n\n // Determine which levels to patch\n this.patchedLevels = allLogLevels.filter(\n (level) =>\n !(instrumentationOptions?.disabledLevels ?? ConsoleInstrumentation.defaultDisabledLevels).includes(level)\n );\n\n // Patch console methods\n this.patchedLevels.forEach((level) => {\n console[level] = (...args: unknown[]) => {\n // Prevent re-entry to avoid infinite loops\n if (this.isProcessing) {\n this.originalConsole[level]?.(...args);\n return;\n }\n\n this.isProcessing = true;\n try {\n if (level === LogLevel.ERROR && !instrumentationOptions?.consoleErrorAsLog) {\n // Handle console.error as an error with advanced serialization\n const { value, type, stackFrames } = getDetailsFromConsoleErrorArgs(args, this.errorSerializer);\n\n const context = { mechanism: ErrorMechanism.CONSOLE };\n\n if (value && !type && !stackFrames) {\n // Simple error without stack frames\n this.api.pushError(new Error(ConsoleInstrumentation.consoleErrorPrefix + value), {\n context,\n fatal: false,\n });\n } else {\n // Error with type and/or stack frames (type from error.name, matches Web SDK)\n this.api.pushError(new Error(ConsoleInstrumentation.consoleErrorPrefix + (value ?? '')), {\n context,\n fatal: false,\n type,\n stackFrames,\n });\n }\n } else if (level === LogLevel.ERROR && instrumentationOptions?.consoleErrorAsLog) {\n // Handle console.error as a log with error details in context\n const { value, type, stackFrames } = getDetailsFromConsoleErrorArgs(args, this.errorSerializer);\n\n this.api.pushLog(value ? [ConsoleInstrumentation.consoleErrorPrefix + value] : args, {\n level,\n context: {\n value: value ?? '',\n type: type ?? '',\n stackFrames: stackFrames?.length ? defaultErrorArgsSerializer(stackFrames) : '',\n },\n });\n } else {\n // Handle other log levels normally\n this.api.pushLog(args, { level });\n }\n } catch (_err) {\n // Silently ignore errors to prevent infinite loops during bootstrap\n } finally {\n // Always call original console method (still protected by isProcessing flag)\n this.originalConsole[level]?.(...args);\n this.isProcessing = false;\n }\n };\n });\n }\n\n /**\n * Restore original console methods\n * Call this to clean up and unpatch the console\n */\n unpatch(): void {\n this.patchedLevels.forEach((level) => {\n if (this.originalConsole[level]) {\n console[level] = this.originalConsole[level];\n }\n });\n\n this.patchedLevels = [];\n }\n}\n"]}
@@ -50,51 +50,40 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
50
50
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
51
  }
52
52
  };
53
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
54
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
55
+ if (ar || !(i in from)) {
56
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
57
+ ar[i] = from[i];
58
+ }
59
+ }
60
+ return to.concat(ar || Array.prototype.slice.call(from));
61
+ };
53
62
  Object.defineProperty(exports, "__esModule", { value: true });
54
- exports.CrashReportingInstrumentation = void 0;
63
+ exports.BaseCrashReportingInstrumentation = void 0;
55
64
  var react_native_1 = require("react-native");
56
65
  var faro_core_1 = require("@grafana/faro-core");
57
- var const_1 = require("../errors/const");
66
+ var nativeTombstoneTrace_1 = require("./android/nativeTombstoneTrace");
58
67
  /**
59
- * Crash Reporting Instrumentation (Experimental).
60
- *
61
- * Retrieves crash reports from previous app sessions and sends them via Faro API.
62
- *
63
- * **Platform Support**:
64
- * - **Android**: Uses ApplicationExitInfo API (Android 11+ / API 30+)
65
- * Captures: CRASH, CRASH_NATIVE, ANR, LOW_MEMORY, EXCESSIVE_RESOURCE_USAGE
66
- * - **iOS**: Uses PLCrashReporter (requires adding dependency to podspec)
67
- * Captures: Signal crashes (SIGSEGV, SIGABRT, etc.) and Mach exceptions
68
- *
69
- * **Note**: This instrumentation only retrieves crash data from previous sessions.
70
- * The crash itself terminates the app, so the report is sent on next app launch.
68
+ * Abstract base class for platform-specific crash reporting implementations.
71
69
  *
72
- * @example
73
- * ```typescript
74
- * import { initializeFaro, CrashReportingInstrumentation } from '@grafana/faro-react-native';
75
- *
76
- * initializeFaro({
77
- * url: 'https://collector.example.com',
78
- * instrumentations: [
79
- * new CrashReportingInstrumentation(),
80
- * ],
81
- * });
82
- * ```
70
+ * Defines the common contract that both Android and iOS implementations must follow.
71
+ * Handles the shared logic for retrieving crash reports from native modules and
72
+ * processing them, while delegating platform-specific parsing and validation to subclasses.
83
73
  */
84
- var CrashReportingInstrumentation = /** @class */ (function (_super) {
85
- __extends(CrashReportingInstrumentation, _super);
86
- function CrashReportingInstrumentation(options) {
74
+ var BaseCrashReportingInstrumentation = /** @class */ (function (_super) {
75
+ __extends(BaseCrashReportingInstrumentation, _super);
76
+ function BaseCrashReportingInstrumentation(options) {
87
77
  if (options === void 0) { options = {}; }
88
78
  var _a;
89
79
  var _this = _super.call(this) || this;
90
- _this.name = '@grafana/faro-react-native:instrumentation-crash';
91
- _this.version = faro_core_1.VERSION;
92
80
  _this.options = {
93
81
  enabled: (_a = options.enabled) !== null && _a !== void 0 ? _a : true,
82
+ releaseBundleFilename: options.releaseBundleFilename,
94
83
  };
95
84
  return _this;
96
85
  }
97
- CrashReportingInstrumentation.prototype.initialize = function () {
86
+ BaseCrashReportingInstrumentation.prototype.initialize = function () {
98
87
  return __awaiter(this, void 0, void 0, function () {
99
88
  var nativeModule;
100
89
  return __generator(this, function (_a) {
@@ -110,38 +99,22 @@ var CrashReportingInstrumentation = /** @class */ (function (_super) {
110
99
  return [2 /*return*/];
111
100
  }
112
101
  this.logDebug('Initializing crash reporting instrumentation');
113
- // Wait for session attributes to be populated before sending crash reports
114
- // This ensures crash reports include full session metadata
102
+ // Wait for session attributes before sending crash reports
115
103
  return [4 /*yield*/, this.waitForSessionAttributes()];
116
104
  case 1:
117
- // Wait for session attributes to be populated before sending crash reports
118
- // This ensures crash reports include full session metadata
105
+ // Wait for session attributes before sending crash reports
119
106
  _a.sent();
120
- // Get crash reports from previous session
107
+ // Get and process crash reports from previous session
121
108
  return [4 /*yield*/, this.processCrashReports(nativeModule)];
122
109
  case 2:
123
- // Get crash reports from previous session
110
+ // Get and process crash reports from previous session
124
111
  _a.sent();
125
112
  return [2 /*return*/];
126
113
  }
127
114
  });
128
115
  });
129
116
  };
130
- /**
131
- * Wait for session attributes to be populated.
132
- *
133
- * Crash reports are sent in a new session, so we need to wait for
134
- * SessionInstrumentation to finish collecting device info, OS version, etc.
135
- * before sending the crash report. Otherwise, the crash report will be missing
136
- * session metadata.
137
- *
138
- * This checks for multiple device-specific attributes that are collected
139
- * asynchronously (device_id, device_os_detail, device_model_name) to ensure
140
- * the async getSessionAttributes() call has completed.
141
- *
142
- * @param maxWaitMs Maximum time to wait in milliseconds (default 10000ms)
143
- */
144
- CrashReportingInstrumentation.prototype.waitForSessionAttributes = function () {
117
+ BaseCrashReportingInstrumentation.prototype.waitForSessionAttributes = function () {
145
118
  return __awaiter(this, arguments, void 0, function (maxWaitMs) {
146
119
  var startTime, pollInterval, checkCount, sessionAttrs, attrCount, attrKeys, hasDeviceId, hasDeviceOsDetail, hasDeviceModelName, elapsed, finalAttrs, finalAttrCount, finalAttrKeys;
147
120
  var _a, _b, _c, _d, _e, _f;
@@ -178,13 +151,10 @@ var CrashReportingInstrumentation = /** @class */ (function (_super) {
178
151
  }
179
152
  }
180
153
  catch (error) {
181
- // Continue waiting if we can't access metas yet
182
154
  this.logDebug("Check #".concat(checkCount, ": Error accessing metas: ").concat(error));
183
155
  }
184
- // Wait before next check
185
156
  return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, pollInterval); })];
186
157
  case 2:
187
- // Wait before next check
188
158
  _g.sent();
189
159
  return [3 /*break*/, 1];
190
160
  case 3:
@@ -197,16 +167,16 @@ var CrashReportingInstrumentation = /** @class */ (function (_super) {
197
167
  });
198
168
  });
199
169
  };
200
- CrashReportingInstrumentation.prototype.getNativeModule = function () {
170
+ BaseCrashReportingInstrumentation.prototype.getNativeModule = function () {
201
171
  var FaroReactNativeModule = react_native_1.NativeModules.FaroReactNativeModule;
202
172
  if (!FaroReactNativeModule) {
203
173
  return null;
204
174
  }
205
175
  return FaroReactNativeModule;
206
176
  };
207
- CrashReportingInstrumentation.prototype.processCrashReports = function (nativeModule) {
177
+ BaseCrashReportingInstrumentation.prototype.processCrashReports = function (nativeModule) {
208
178
  return __awaiter(this, void 0, void 0, function () {
209
- var crashReports, _i, crashReports_1, crashJson, crash, error_1;
179
+ var crashReports, reportedTimestamps, _i, crashReports_1, crashJson, crash, error_1;
210
180
  return __generator(this, function (_a) {
211
181
  switch (_a.label) {
212
182
  case 0:
@@ -224,22 +194,34 @@ var CrashReportingInstrumentation = /** @class */ (function (_super) {
224
194
  return [2 /*return*/];
225
195
  }
226
196
  this.logDebug("Processing ".concat(crashReports.length, " crash report(s) from previous session"));
197
+ reportedTimestamps = new Set();
227
198
  for (_i = 0, crashReports_1 = crashReports; _i < crashReports_1.length; _i++) {
228
199
  crashJson = crashReports_1[_i];
229
200
  try {
230
201
  this.logDebug("Parsing crash report JSON: ".concat(crashJson.substring(0, 200), "..."));
231
202
  crash = JSON.parse(crashJson);
203
+ if (crash.timestamp && reportedTimestamps.has(crash.timestamp)) {
204
+ this.logDebug("Skipping duplicate crash report at ".concat(crash.timestamp));
205
+ continue;
206
+ }
207
+ if (this.shouldSkipCrashReport(crash)) {
208
+ this.logDebug("Skipping crash report at ".concat(crash.timestamp, " (platform-specific skip logic)"));
209
+ continue;
210
+ }
211
+ if (crash.timestamp) {
212
+ reportedTimestamps.add(crash.timestamp);
213
+ }
232
214
  this.sendCrashReport(crash);
233
215
  }
234
216
  catch (parseError) {
235
- // If parsing fails, still try to report something
236
217
  this.logError('Failed to parse crash report JSON', parseError);
237
218
  this.api.pushError(new Error('Application crash (parse error)'), {
238
219
  context: {
239
- mechanism: const_1.ErrorMechanism.CRASH,
220
+ mechanism: 'crash',
240
221
  parseError: String(parseError),
241
- raw: crashJson.substring(0, 500), // Limit size
222
+ raw: crashJson.substring(0, 500),
242
223
  },
224
+ fatal: true,
243
225
  type: 'crash',
244
226
  });
245
227
  }
@@ -254,12 +236,16 @@ var CrashReportingInstrumentation = /** @class */ (function (_super) {
254
236
  });
255
237
  });
256
238
  };
257
- CrashReportingInstrumentation.prototype.sendCrashReport = function (crash) {
258
- var errorMessage = this.getErrorMessage(crash);
239
+ BaseCrashReportingInstrumentation.prototype.sendCrashReport = function (crash) {
240
+ // Platform-specific parsing
241
+ var parsedTrace = crash.trace ? this.parseCrashTrace(crash.trace) : null;
242
+ var errorMessage = this.resolveCrashErrorMessage(crash, parsedTrace).trim() || 'Application crash';
243
+ // Use a message-only Error so pushError does not capture the JS reporter stack
259
244
  var error = new Error(errorMessage);
260
- // Build context from crash data (matching Flutter pattern)
245
+ error.stack = undefined;
246
+ // Build context from crash data
261
247
  var context = {
262
- mechanism: const_1.ErrorMechanism.CRASH,
248
+ mechanism: 'crash',
263
249
  };
264
250
  if (crash.trace) {
265
251
  context['trace'] = crash.trace;
@@ -282,48 +268,69 @@ var CrashReportingInstrumentation = /** @class */ (function (_super) {
282
268
  if (crash.importance !== undefined) {
283
269
  context['importance'] = String(crash.importance);
284
270
  }
285
- // Push as error via Faro API (matching Flutter pattern)
271
+ // Platform-specific context
272
+ this.buildPlatformContext(parsedTrace, context);
273
+ // Platform-specific stack frames
274
+ var stackFrames = this.getStackFrames(parsedTrace);
275
+ // Warnings for missing/unparseable traces
276
+ if (!stackFrames.length && crash.trace) {
277
+ this.logWarn(this.getParseFailureWarning());
278
+ }
279
+ else if (!crash.trace) {
280
+ this.logWarn(this.getTraceUnavailableWarning());
281
+ }
282
+ else if ((0, nativeTombstoneTrace_1.looksLikeNativeTombstoneTrace)(crash.trace)) {
283
+ var framePreview = crash.trace
284
+ .split('\n')
285
+ .map(function (line) { return line.trim(); })
286
+ .find(function (line) { return /#\d+\s+pc\s+/i.test(line); });
287
+ this.logInfo("[Faro crash native] Sending tombstone trace (".concat(crash.trace.split('\n').length, " lines) preview=").concat(framePreview !== null && framePreview !== void 0 ? framePreview : 'n/a'));
288
+ }
286
289
  this.api.pushError(error, {
287
- type: 'crash',
290
+ stackFrames: stackFrames,
288
291
  context: context,
292
+ type: 'crash',
293
+ fatal: true,
289
294
  });
290
- this.logDebug("Reported crash: ".concat(crash.reason, " at ").concat(crash.timestamp));
295
+ this.logDebug("Sent crash report: ".concat(errorMessage));
291
296
  };
292
- /**
293
- * Build error message matching Flutter SDK format:
294
- * "{reason}: {description}, status: {status}"
295
- */
296
- CrashReportingInstrumentation.prototype.getErrorMessage = function (crash) {
297
- var _a;
298
- var reason = crash.reason || 'UNKNOWN';
299
- var status = (_a = crash.status) !== null && _a !== void 0 ? _a : 0;
300
- var description;
301
- switch (crash.reason) {
302
- case 'ANR':
303
- description = 'Application Not Responding';
304
- break;
305
- case 'CRASH':
306
- description = 'Application crash (Java/Kotlin)';
307
- break;
308
- case 'CRASH_NATIVE':
309
- description = 'Application crash (Native)';
310
- break;
311
- case 'LOW_MEMORY':
312
- description = 'Application terminated due to low memory';
313
- break;
314
- case 'EXCESSIVE_RESOURCE_USAGE':
315
- description = 'Application terminated due to excessive resource usage';
316
- break;
317
- case 'INITIALIZATION_FAILURE':
318
- description = 'Application failed to initialize';
319
- break;
320
- default:
321
- description = crash.description || 'Application crash';
322
- break;
297
+ // Logging helpers
298
+ BaseCrashReportingInstrumentation.prototype.logDebug = function (message) {
299
+ var _a, _b;
300
+ var args = [];
301
+ for (var _i = 1; _i < arguments.length; _i++) {
302
+ args[_i - 1] = arguments[_i];
303
+ }
304
+ (_b = (_a = this.internalLogger) === null || _a === void 0 ? void 0 : _a.debug) === null || _b === void 0 ? void 0 : _b.call.apply(_b, __spreadArray([_a, message], args, false));
305
+ };
306
+ BaseCrashReportingInstrumentation.prototype.logInfo = function (message) {
307
+ var _a, _b;
308
+ var args = [];
309
+ for (var _i = 1; _i < arguments.length; _i++) {
310
+ args[_i - 1] = arguments[_i];
323
311
  }
324
- return "".concat(reason, ": ").concat(description, ", status: ").concat(status);
312
+ (_b = (_a = this.internalLogger) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.call.apply(_b, __spreadArray([_a, message], args, false));
313
+ };
314
+ BaseCrashReportingInstrumentation.prototype.logWarn = function (message) {
315
+ var _a, _b;
316
+ var args = [];
317
+ for (var _i = 1; _i < arguments.length; _i++) {
318
+ args[_i - 1] = arguments[_i];
319
+ }
320
+ (_b = (_a = this.internalLogger) === null || _a === void 0 ? void 0 : _a.warn) === null || _b === void 0 ? void 0 : _b.call.apply(_b, __spreadArray([_a, message], args, false));
321
+ };
322
+ BaseCrashReportingInstrumentation.prototype.logError = function (message) {
323
+ var _a, _b;
324
+ var args = [];
325
+ for (var _i = 1; _i < arguments.length; _i++) {
326
+ args[_i - 1] = arguments[_i];
327
+ }
328
+ (_b = (_a = this.internalLogger) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call.apply(_b, __spreadArray([_a, message], args, false));
329
+ };
330
+ BaseCrashReportingInstrumentation.prototype.unpatch = function () {
331
+ // No patching to undo
325
332
  };
326
- return CrashReportingInstrumentation;
333
+ return BaseCrashReportingInstrumentation;
327
334
  }(faro_core_1.BaseInstrumentation));
328
- exports.CrashReportingInstrumentation = CrashReportingInstrumentation;
329
- //# sourceMappingURL=instrumentation.js.map
335
+ exports.BaseCrashReportingInstrumentation = BaseCrashReportingInstrumentation;
336
+ //# sourceMappingURL=BaseCrashReportingInstrumentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseCrashReportingInstrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/crashReporting/BaseCrashReportingInstrumentation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAA6C;AAE7C,gDAAyD;AAEzD,uEAA+E;AAG/E;;;;;;GAMG;AACH;IAAgE,qDAAmB;IAMjF,2CAAY,OAAmC;QAAnC,wBAAA,EAAA,YAAmC;;QAC7C,YAAA,MAAK,WAAE,SAAC;QACR,KAAI,CAAC,OAAO,GAAG;YACb,OAAO,EAAE,MAAA,OAAO,CAAC,OAAO,mCAAI,IAAI;YAChC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;SACrD,CAAC;;IACJ,CAAC;IAEK,sDAAU,GAAhB;;;;;;wBACE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;4BAC1B,IAAI,CAAC,QAAQ,CAAC,6BAA6B,CAAC,CAAC;4BAC7C,sBAAO;wBACT,CAAC;wBAEK,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;wBAC5C,IAAI,CAAC,YAAY,EAAE,CAAC;4BAClB,IAAI,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC;4BAChE,sBAAO;wBACT,CAAC;wBAED,IAAI,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CAAC;wBAE9D,2DAA2D;wBAC3D,qBAAM,IAAI,CAAC,wBAAwB,EAAE,EAAA;;wBADrC,2DAA2D;wBAC3D,SAAqC,CAAC;wBAEtC,sDAAsD;wBACtD,qBAAM,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,EAAA;;wBAD5C,sDAAsD;wBACtD,SAA4C,CAAC;;;;;KAC9C;IAqCa,oEAAwB,GAAtC;4DAAuC,SAAiB;;;YAAjB,0BAAA,EAAA,iBAAiB;;;;wBAChD,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBACvB,YAAY,GAAG,GAAG,CAAC;wBACrB,UAAU,GAAG,CAAC,CAAC;;;6BAEZ,CAAA,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,SAAS,CAAA;wBACvC,UAAU,EAAE,CAAC;wBACb,IAAI,CAAC;4BACG,YAAY,GAAG,MAAA,MAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAK,0CAAE,OAAO,0CAAE,UAAU,CAAC;4BAE5D,IAAI,YAAY,EAAE,CAAC;gCACX,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;gCAC7C,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;gCAQrD,WAAW,GAAG,WAAW,IAAI,YAAY,IAAI,YAAY,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC;gCACrF,iBAAiB,GACrB,kBAAkB,IAAI,YAAY,IAAI,YAAY,CAAC,kBAAkB,CAAC,KAAK,SAAS,CAAC;gCACjF,kBAAkB,GAAG,mBAAmB,IAAI,YAAY,CAAC;gCAE/D,IAAI,WAAW,IAAI,iBAAiB,IAAI,kBAAkB,EAAE,CAAC;oCACrD,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;oCACvC,IAAI,CAAC,QAAQ,CAAC,yCAAkC,OAAO,iBAAO,UAAU,sBAAY,SAAS,YAAS,CAAC,CAAC;oCACxG,sBAAO;gCACT,CAAC;qCAAM,CAAC;oCACN,IAAI,CAAC,QAAQ,CACX,iBAAU,UAAU,qBAAW,SAAS,kCAAwB,QAAQ,2DAAiD,WAAW,gCAAsB,iBAAiB,iCAAuB,kBAAkB,CAAE,CACvN,CAAC;gCACJ,CAAC;4BACH,CAAC;iCAAM,CAAC;gCACN,IAAI,CAAC,QAAQ,CAAC,iBAAU,UAAU,0CAAuC,CAAC,CAAC;4BAC7E,CAAC;wBACH,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,IAAI,CAAC,QAAQ,CAAC,iBAAU,UAAU,sCAA4B,KAAK,CAAE,CAAC,CAAC;wBACzE,CAAC;wBAED,qBAAM,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,EAAjC,CAAiC,CAAC,EAAA;;wBAAjE,SAAiE,CAAC;;;wBAG9D,UAAU,GAAG,MAAA,MAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAK,0CAAE,OAAO,0CAAE,UAAU,CAAC;wBACpD,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;wBACjE,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;wBACpF,IAAI,CAAC,OAAO,CACV,6CAAsC,SAAS,yBAAe,UAAU,sBAAY,cAAc,qBAAW,aAAa,oCAAiC,CAC5J,CAAC;;;;;KACH;IAEO,2DAAe,GAAvB;QACU,IAAA,qBAAqB,GAAK,4BAAa,sBAAlB,CAAmB;QAEhD,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAEa,+DAAmB,GAAjC,UAAkC,YAAwD;;;;;;;wBAEtF,IAAI,OAAO,YAAY,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;4BACtD,IAAI,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC;4BACrD,sBAAO;wBACT,CAAC;wBAED,IAAI,CAAC,QAAQ,CAAC,yDAAyD,CAAC,CAAC;wBACnD,qBAAM,YAAY,CAAC,cAAc,EAAE,EAAA;;wBAAnD,YAAY,GAAG,CAAC,SAAmC,CAAoB;wBAE7E,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BAC/C,IAAI,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC;4BACxD,sBAAO;wBACT,CAAC;wBAED,IAAI,CAAC,QAAQ,CAAC,qBAAc,YAAY,CAAC,MAAM,2CAAwC,CAAC,CAAC;wBAEnF,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;wBAE7C,WAAoC,EAAZ,6BAAY,EAAZ,0BAAY,EAAZ,IAAY,EAAE,CAAC;4BAA5B,SAAS;4BAClB,IAAI,CAAC;gCACH,IAAI,CAAC,QAAQ,CAAC,qCAA8B,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,QAAK,CAAC,CAAC;gCACxE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAgB,CAAC;gCAEnD,IAAI,KAAK,CAAC,SAAS,IAAI,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;oCAC/D,IAAI,CAAC,QAAQ,CAAC,6CAAsC,KAAK,CAAC,SAAS,CAAE,CAAC,CAAC;oCACvE,SAAS;gCACX,CAAC;gCAED,IAAI,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;oCACtC,IAAI,CAAC,QAAQ,CAAC,mCAA4B,KAAK,CAAC,SAAS,oCAAiC,CAAC,CAAC;oCAC5F,SAAS;gCACX,CAAC;gCAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oCACpB,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gCAC1C,CAAC;gCAED,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;4BAC9B,CAAC;4BAAC,OAAO,UAAU,EAAE,CAAC;gCACpB,IAAI,CAAC,QAAQ,CAAC,mCAAmC,EAAE,UAAU,CAAC,CAAC;gCAC/D,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,EAAE;oCAC/D,OAAO,EAAE;wCACP,SAAS,EAAE,OAAO;wCAClB,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;wCAC9B,GAAG,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;qCACjC;oCACD,KAAK,EAAE,IAAI;oCACX,IAAI,EAAE,OAAO;iCACd,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC;;;;wBAED,IAAI,CAAC,QAAQ,CAAC,iCAAiC,EAAE,OAAK,CAAC,CAAC;;;;;;KAE3D;IAEO,2DAAe,GAAvB,UAAwB,KAAkB;QACxC,4BAA4B;QAC5B,IAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3E,IAAM,YAAY,GAAG,IAAI,CAAC,wBAAwB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,mBAAmB,CAAC;QAErG,+EAA+E;QAC/E,IAAM,KAAK,GAAG,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;QACtC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;QAExB,gCAAgC;QAChC,IAAM,OAAO,GAA2B;YACtC,SAAS,EAAE,OAAO;SACnB,CAAC;QAEF,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;QACjC,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACnC,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACnC,OAAO,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACnD,CAAC;QAED,4BAA4B;QAC5B,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAEhD,iCAAiC;QACjC,IAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAErD,0CAA0C;QAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,IAAA,oDAA6B,EAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,IAAM,YAAY,GAAG,KAAK,CAAC,KAAK;iBAC7B,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,UAAC,IAAI,IAAK,OAAA,IAAI,CAAC,IAAI,EAAE,EAAX,CAAW,CAAC;iBAC1B,IAAI,CAAC,UAAC,IAAI,IAAK,OAAA,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAA1B,CAA0B,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO,CACV,uDAAgD,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,6BAAmB,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,KAAK,CAAE,CACzH,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE;YACxB,WAAW,aAAA;YACX,OAAO,SAAA;YACP,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,6BAAsB,YAAY,CAAE,CAAC,CAAC;IACtD,CAAC;IAED,kBAAkB;IACT,oDAAQ,GAAjB,UAAkB,OAAe;;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QAC/C,MAAA,MAAA,IAAI,CAAC,cAAc,0CAAE,KAAK,4EAAG,OAAO,GAAK,IAAI,SAAC,CAAC;IACjD,CAAC;IAEQ,mDAAO,GAAhB,UAAiB,OAAe;;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QAC9C,MAAA,MAAA,IAAI,CAAC,cAAc,0CAAE,IAAI,4EAAG,OAAO,GAAK,IAAI,SAAC,CAAC;IAChD,CAAC;IAEQ,mDAAO,GAAhB,UAAiB,OAAe;;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QAC9C,MAAA,MAAA,IAAI,CAAC,cAAc,0CAAE,IAAI,4EAAG,OAAO,GAAK,IAAI,SAAC,CAAC;IAChD,CAAC;IAEQ,oDAAQ,GAAjB,UAAkB,OAAe;;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QAC/C,MAAA,MAAA,IAAI,CAAC,cAAc,0CAAE,KAAK,4EAAG,OAAO,GAAK,IAAI,SAAC,CAAC;IACjD,CAAC;IAED,mDAAO,GAAP;QACE,sBAAsB;IACxB,CAAC;IACH,wCAAC;AAAD,CAAC,AApRD,CAAgE,+BAAmB,GAoRlF;AApRqB,8EAAiC","sourcesContent":["import { NativeModules } from 'react-native';\n\nimport { BaseInstrumentation } from '@grafana/faro-core';\n\nimport { looksLikeNativeTombstoneTrace } from './android/nativeTombstoneTrace';\nimport type { CrashReport, CrashReportingOptions } from './types';\n\n/**\n * Abstract base class for platform-specific crash reporting implementations.\n *\n * Defines the common contract that both Android and iOS implementations must follow.\n * Handles the shared logic for retrieving crash reports from native modules and\n * processing them, while delegating platform-specific parsing and validation to subclasses.\n */\nexport abstract class BaseCrashReportingInstrumentation extends BaseInstrumentation {\n abstract override readonly name: string;\n abstract override readonly version: string;\n\n protected readonly options: { enabled: boolean; releaseBundleFilename?: string };\n\n constructor(options: CrashReportingOptions = {}) {\n super();\n this.options = {\n enabled: options.enabled ?? true,\n releaseBundleFilename: options.releaseBundleFilename,\n };\n }\n\n async initialize(): Promise<void> {\n if (!this.options.enabled) {\n this.logDebug('Crash reporting is disabled');\n return;\n }\n\n const nativeModule = this.getNativeModule();\n if (!nativeModule) {\n this.logWarn('Native module not available for crash reporting');\n return;\n }\n\n this.logDebug('Initializing crash reporting instrumentation');\n\n // Wait for session attributes before sending crash reports\n await this.waitForSessionAttributes();\n\n // Get and process crash reports from previous session\n await this.processCrashReports(nativeModule);\n }\n\n /**\n * Platform-specific: Parse a crash trace string into structured stack frames.\n */\n protected abstract parseCrashTrace(trace: string): any | null;\n\n /**\n * Platform-specific: Resolve human-readable error message from crash data.\n */\n protected abstract resolveCrashErrorMessage(crash: CrashReport, parsedTrace: any | null): string;\n\n /**\n * Platform-specific: Determine if a crash report should be skipped.\n */\n protected abstract shouldSkipCrashReport(crash: CrashReport): boolean;\n\n /**\n * Platform-specific: Extract stack frames from parsed trace.\n */\n protected abstract getStackFrames(parsedTrace: any | null): any[];\n\n /**\n * Platform-specific: Build platform-specific context from parsed trace.\n */\n protected abstract buildPlatformContext(parsedTrace: any | null, context: Record<string, string>): void;\n\n /**\n * Platform-specific: Get warning message when trace parsing fails.\n */\n protected abstract getParseFailureWarning(): string;\n\n /**\n * Platform-specific: Get warning message when trace is unavailable.\n */\n protected abstract getTraceUnavailableWarning(): string;\n\n private async waitForSessionAttributes(maxWaitMs = 10000): Promise<void> {\n const startTime = Date.now();\n const pollInterval = 200;\n let checkCount = 0;\n\n while (Date.now() - startTime < maxWaitMs) {\n checkCount++;\n try {\n const sessionAttrs = this.metas?.value?.session?.attributes;\n\n if (sessionAttrs) {\n const attrCount = Object.keys(sessionAttrs).length;\n const attrKeys = JSON.stringify(Object.keys(sessionAttrs));\n\n // Look for multiple device-specific attributes that indicate full async collection is done.\n // getSessionAttributes() collects these asynchronously:\n // - device_id (SDK installation id, kept as a flat attr during migration)\n // - device_os_detail (async getDeviceOsDetail)\n // - device_model_name (DeviceInfo.getDeviceNameSync)\n // All three should be present when collection is complete.\n const hasDeviceId = 'device_id' in sessionAttrs && sessionAttrs['device_id'] !== 'unknown';\n const hasDeviceOsDetail =\n 'device_os_detail' in sessionAttrs && sessionAttrs['device_os_detail'] !== 'unknown';\n const hasDeviceModelName = 'device_model_name' in sessionAttrs;\n\n if (hasDeviceId && hasDeviceOsDetail && hasDeviceModelName) {\n const elapsed = Date.now() - startTime;\n this.logDebug(`Session attributes ready after ${elapsed}ms (${checkCount} checks, ${attrCount} attrs)`);\n return;\n } else {\n this.logDebug(\n `Check #${checkCount}: Found ${attrCount} session attributes: ${attrKeys} but still missing required attrs - device_id:${hasDeviceId}, device_os_detail:${hasDeviceOsDetail}, device_model_name:${hasDeviceModelName}`\n );\n }\n } else {\n this.logDebug(`Check #${checkCount}: No session attributes available yet`);\n }\n } catch (error) {\n this.logDebug(`Check #${checkCount}: Error accessing metas: ${error}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n }\n\n const finalAttrs = this.metas?.value?.session?.attributes;\n const finalAttrCount = finalAttrs ? Object.keys(finalAttrs).length : 0;\n const finalAttrKeys = finalAttrs ? JSON.stringify(Object.keys(finalAttrs)) : 'none';\n this.logWarn(\n `Session attributes not ready after ${maxWaitMs}ms timeout (${checkCount} checks, ${finalAttrCount} attrs: ${finalAttrKeys}). Sending crash report anyway.`\n );\n }\n\n private getNativeModule(): typeof NativeModules.FaroReactNativeModule | null {\n const { FaroReactNativeModule } = NativeModules;\n\n if (!FaroReactNativeModule) {\n return null;\n }\n\n return FaroReactNativeModule;\n }\n\n private async processCrashReports(nativeModule: typeof NativeModules.FaroReactNativeModule): Promise<void> {\n try {\n if (typeof nativeModule.getCrashReport !== 'function') {\n this.logDebug('getCrashReport method not available');\n return;\n }\n\n this.logDebug('Attempting to retrieve crash reports from native module');\n const crashReports = (await nativeModule.getCrashReport()) as string[] | null;\n\n if (!crashReports || crashReports.length === 0) {\n this.logDebug('No crash reports from previous session');\n return;\n }\n\n this.logDebug(`Processing ${crashReports.length} crash report(s) from previous session`);\n\n const reportedTimestamps = new Set<number>();\n\n for (const crashJson of crashReports) {\n try {\n this.logDebug(`Parsing crash report JSON: ${crashJson.substring(0, 200)}...`);\n const crash = JSON.parse(crashJson) as CrashReport;\n\n if (crash.timestamp && reportedTimestamps.has(crash.timestamp)) {\n this.logDebug(`Skipping duplicate crash report at ${crash.timestamp}`);\n continue;\n }\n\n if (this.shouldSkipCrashReport(crash)) {\n this.logDebug(`Skipping crash report at ${crash.timestamp} (platform-specific skip logic)`);\n continue;\n }\n\n if (crash.timestamp) {\n reportedTimestamps.add(crash.timestamp);\n }\n\n this.sendCrashReport(crash);\n } catch (parseError) {\n this.logError('Failed to parse crash report JSON', parseError);\n this.api.pushError(new Error('Application crash (parse error)'), {\n context: {\n mechanism: 'crash',\n parseError: String(parseError),\n raw: crashJson.substring(0, 500),\n },\n fatal: true,\n type: 'crash',\n });\n }\n }\n } catch (error) {\n this.logError('Failed to process crash reports', error);\n }\n }\n\n private sendCrashReport(crash: CrashReport): void {\n // Platform-specific parsing\n const parsedTrace = crash.trace ? this.parseCrashTrace(crash.trace) : null;\n const errorMessage = this.resolveCrashErrorMessage(crash, parsedTrace).trim() || 'Application crash';\n\n // Use a message-only Error so pushError does not capture the JS reporter stack\n const error = new Error(errorMessage);\n error.stack = undefined;\n\n // Build context from crash data\n const context: Record<string, string> = {\n mechanism: 'crash',\n };\n\n if (crash.trace) {\n context['trace'] = crash.trace;\n }\n if (crash.signal) {\n context['signal'] = crash.signal;\n }\n if (crash.timestamp) {\n context['timestamp'] = String(crash.timestamp);\n }\n if (crash.description) {\n context['description'] = crash.description;\n }\n if (crash.processName) {\n context['processName'] = crash.processName;\n }\n if (crash.pid) {\n context['pid'] = String(crash.pid);\n }\n if (crash.importance !== undefined) {\n context['importance'] = String(crash.importance);\n }\n\n // Platform-specific context\n this.buildPlatformContext(parsedTrace, context);\n\n // Platform-specific stack frames\n const stackFrames = this.getStackFrames(parsedTrace);\n\n // Warnings for missing/unparseable traces\n if (!stackFrames.length && crash.trace) {\n this.logWarn(this.getParseFailureWarning());\n } else if (!crash.trace) {\n this.logWarn(this.getTraceUnavailableWarning());\n } else if (looksLikeNativeTombstoneTrace(crash.trace)) {\n const framePreview = crash.trace\n .split('\\n')\n .map((line) => line.trim())\n .find((line) => /#\\d+\\s+pc\\s+/i.test(line));\n this.logInfo(\n `[Faro crash native] Sending tombstone trace (${crash.trace.split('\\n').length} lines) preview=${framePreview ?? 'n/a'}`\n );\n }\n\n this.api.pushError(error, {\n stackFrames,\n context,\n type: 'crash',\n fatal: true,\n });\n\n this.logDebug(`Sent crash report: ${errorMessage}`);\n }\n\n // Logging helpers\n override logDebug(message: string, ...args: any[]): void {\n this.internalLogger?.debug?.(message, ...args);\n }\n\n override logInfo(message: string, ...args: any[]): void {\n this.internalLogger?.info?.(message, ...args);\n }\n\n override logWarn(message: string, ...args: any[]): void {\n this.internalLogger?.warn?.(message, ...args);\n }\n\n override logError(message: string, ...args: any[]): void {\n this.internalLogger?.error?.(message, ...args);\n }\n\n unpatch(): void {\n // No patching to undo\n }\n}\n"]}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.NoOpCrashReportingInstrumentation = void 0;
19
+ var faro_core_1 = require("@grafana/faro-core");
20
+ /**
21
+ * Crash reporting stub for platforms other than Android and iOS (e.g. web, macOS, Windows).
22
+ */
23
+ var NoOpCrashReportingInstrumentation = /** @class */ (function (_super) {
24
+ __extends(NoOpCrashReportingInstrumentation, _super);
25
+ function NoOpCrashReportingInstrumentation(_options) {
26
+ if (_options === void 0) { _options = {}; }
27
+ var _this = _super.call(this) || this;
28
+ _this.name = '@grafana/faro-react-native:instrumentation-crash-noop';
29
+ _this.version = faro_core_1.VERSION;
30
+ return _this;
31
+ }
32
+ NoOpCrashReportingInstrumentation.prototype.initialize = function () {
33
+ this.logDebug('Crash reporting is not supported on this platform');
34
+ };
35
+ NoOpCrashReportingInstrumentation.prototype.unpatch = function () {
36
+ // No patching to undo
37
+ };
38
+ return NoOpCrashReportingInstrumentation;
39
+ }(faro_core_1.BaseInstrumentation));
40
+ exports.NoOpCrashReportingInstrumentation = NoOpCrashReportingInstrumentation;
41
+ //# sourceMappingURL=NoOpCrashReportingInstrumentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoOpCrashReportingInstrumentation.js","sourceRoot":"","sources":["../../../../src/instrumentations/crashReporting/NoOpCrashReportingInstrumentation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,gDAAkE;AAIlE;;GAEG;AACH;IAAuD,qDAAmB;IAIxE,2CAAY,QAAoC;QAApC,yBAAA,EAAA,aAAoC;QAC9C,YAAA,MAAK,WAAE,SAAC;QAJD,UAAI,GAAG,uDAAuD,CAAC;QAC/D,aAAO,GAAG,mBAAO,CAAC;;IAI3B,CAAC;IAED,sDAAU,GAAV;QACE,IAAI,CAAC,QAAQ,CAAC,mDAAmD,CAAC,CAAC;IACrE,CAAC;IAED,mDAAO,GAAP;QACE,sBAAsB;IACxB,CAAC;IACH,wCAAC;AAAD,CAAC,AAfD,CAAuD,+BAAmB,GAezE;AAfY,8EAAiC","sourcesContent":["import { BaseInstrumentation, VERSION } from '@grafana/faro-core';\n\nimport type { CrashReportingOptions } from './types';\n\n/**\n * Crash reporting stub for platforms other than Android and iOS (e.g. web, macOS, Windows).\n */\nexport class NoOpCrashReportingInstrumentation extends BaseInstrumentation {\n readonly name = '@grafana/faro-react-native:instrumentation-crash-noop';\n readonly version = VERSION;\n\n constructor(_options: CrashReportingOptions = {}) {\n super();\n }\n\n initialize(): void {\n this.logDebug('Crash reporting is not supported on this platform');\n }\n\n unpatch(): void {\n // No patching to undo\n }\n}\n"]}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
18
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
19
+ if (ar || !(i in from)) {
20
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
21
+ ar[i] = from[i];
22
+ }
23
+ }
24
+ return to.concat(ar || Array.prototype.slice.call(from));
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.AndroidCrashReportingInstrumentation = void 0;
28
+ var faro_core_1 = require("@grafana/faro-core");
29
+ var BaseCrashReportingInstrumentation_1 = require("../BaseCrashReportingInstrumentation");
30
+ var crashErrorMessage_1 = require("./crashErrorMessage");
31
+ var parseAndroidCrashTrace_1 = require("./parseAndroidCrashTrace");
32
+ /**
33
+ * Android Crash Reporting Instrumentation.
34
+ *
35
+ * Uses ApplicationExitInfo API (Android 11+ / API 30+) to retrieve crash reports
36
+ * from previous sessions. Captures:
37
+ * - CRASH: Java/Kotlin exception crashes
38
+ * - CRASH_NATIVE: Native (NDK) crashes
39
+ * - LOW_MEMORY: App killed due to low memory
40
+ * - EXCESSIVE_RESOURCE_USAGE: App killed due to excessive resource usage
41
+ *
42
+ * ANRs are reported separately by ANRInstrumentation, not via ApplicationExitInfo replay.
43
+ */
44
+ var AndroidCrashReportingInstrumentation = /** @class */ (function (_super) {
45
+ __extends(AndroidCrashReportingInstrumentation, _super);
46
+ function AndroidCrashReportingInstrumentation() {
47
+ var _this = _super !== null && _super.apply(this, arguments) || this;
48
+ _this.name = '@grafana/faro-react-native:instrumentation-crash-android';
49
+ _this.version = faro_core_1.VERSION;
50
+ return _this;
51
+ }
52
+ AndroidCrashReportingInstrumentation.prototype.parseCrashTrace = function (trace) {
53
+ return (0, parseAndroidCrashTrace_1.parseAndroidCrashTrace)(trace, {
54
+ releaseBundleFilename: this.options.releaseBundleFilename,
55
+ });
56
+ };
57
+ AndroidCrashReportingInstrumentation.prototype.resolveCrashErrorMessage = function (crash, parsedTrace) {
58
+ return (0, crashErrorMessage_1.resolveCrashErrorMessage)(crash, parsedTrace);
59
+ };
60
+ AndroidCrashReportingInstrumentation.prototype.shouldSkipCrashReport = function (crash) {
61
+ return (0, crashErrorMessage_1.shouldSkipCrashReport)(crash);
62
+ };
63
+ AndroidCrashReportingInstrumentation.prototype.getStackFrames = function (parsedTrace) {
64
+ var _a, _b, _c;
65
+ if (!parsedTrace) {
66
+ return [];
67
+ }
68
+ // Android has JS frames, Java/Kotlin frames (R8 retrace), and NDK tombstone rows (.so retrace).
69
+ return __spreadArray(__spreadArray(__spreadArray([], ((_a = parsedTrace.jsFrames) !== null && _a !== void 0 ? _a : []), true), ((_b = parsedTrace.frames) !== null && _b !== void 0 ? _b : []), true), ((_c = parsedTrace.nativeFrames) !== null && _c !== void 0 ? _c : []), true);
70
+ };
71
+ AndroidCrashReportingInstrumentation.prototype.buildPlatformContext = function (parsedTrace, context) {
72
+ // Store the native Java/Kotlin exception class separately for drill-down
73
+ // Plugin overview metrics key off exception_type = 'crash', so keep that stable
74
+ if (parsedTrace === null || parsedTrace === void 0 ? void 0 : parsedTrace.exceptionType) {
75
+ context['nativeExceptionType'] = parsedTrace.exceptionType;
76
+ }
77
+ };
78
+ AndroidCrashReportingInstrumentation.prototype.getParseFailureWarning = function () {
79
+ return 'Native crash trace present but no frames parsed; check Android trace format or UncaughtExceptionHandler cache';
80
+ };
81
+ AndroidCrashReportingInstrumentation.prototype.getTraceUnavailableWarning = function () {
82
+ return 'Native crash trace unavailable (ApplicationExitInfo traceInputStream was null at crash time)';
83
+ };
84
+ return AndroidCrashReportingInstrumentation;
85
+ }(BaseCrashReportingInstrumentation_1.BaseCrashReportingInstrumentation));
86
+ exports.AndroidCrashReportingInstrumentation = AndroidCrashReportingInstrumentation;
87
+ //# sourceMappingURL=AndroidCrashReportingInstrumentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AndroidCrashReportingInstrumentation.js","sourceRoot":"","sources":["../../../../../src/instrumentations/crashReporting/android/AndroidCrashReportingInstrumentation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAA6C;AAE7C,0FAAyF;AAGzF,yDAAsF;AACtF,mEAAgG;AAEhG;;;;;;;;;;;GAWG;AACH;IAA0D,wDAAiC;IAA3F;;QACW,UAAI,GAAG,0DAA0D,CAAC;QAClE,aAAO,GAAG,mBAAO,CAAC;;IAuC7B,CAAC;IArCW,8DAAe,GAAzB,UAA0B,KAAa;QACrC,OAAO,IAAA,+CAAsB,EAAC,KAAK,EAAE;YACnC,qBAAqB,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB;SAC1D,CAAC,CAAC;IACL,CAAC;IAES,uEAAwB,GAAlC,UAAmC,KAAkB,EAAE,WAA2C;QAChG,OAAO,IAAA,4CAAwB,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACtD,CAAC;IAES,oEAAqB,GAA/B,UAAgC,KAAkB;QAChD,OAAO,IAAA,yCAAqB,EAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAES,6DAAc,GAAxB,UAAyB,WAA2C;;QAClE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,gGAAgG;QAChG,qDAAW,CAAC,MAAA,WAAW,CAAC,QAAQ,mCAAI,EAAE,CAAC,SAAK,CAAC,MAAA,WAAW,CAAC,MAAM,mCAAI,EAAE,CAAC,SAAK,CAAC,MAAA,WAAW,CAAC,YAAY,mCAAI,EAAE,CAAC,QAAE;IAC/G,CAAC;IAES,mEAAoB,GAA9B,UAA+B,WAA2C,EAAE,OAA+B;QACzG,yEAAyE;QACzE,gFAAgF;QAChF,IAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,aAAa,EAAE,CAAC;YAC/B,OAAO,CAAC,qBAAqB,CAAC,GAAG,WAAW,CAAC,aAAa,CAAC;QAC7D,CAAC;IACH,CAAC;IAES,qEAAsB,GAAhC;QACE,OAAO,+GAA+G,CAAC;IACzH,CAAC;IAES,yEAA0B,GAApC;QACE,OAAO,8FAA8F,CAAC;IACxG,CAAC;IACH,2CAAC;AAAD,CAAC,AAzCD,CAA0D,qEAAiC,GAyC1F;AAzCY,oFAAoC","sourcesContent":["import { VERSION } from '@grafana/faro-core';\n\nimport { BaseCrashReportingInstrumentation } from '../BaseCrashReportingInstrumentation';\nimport type { CrashReport } from '../types';\n\nimport { resolveCrashErrorMessage, shouldSkipCrashReport } from './crashErrorMessage';\nimport { parseAndroidCrashTrace, type ParsedAndroidCrashTrace } from './parseAndroidCrashTrace';\n\n/**\n * Android Crash Reporting Instrumentation.\n *\n * Uses ApplicationExitInfo API (Android 11+ / API 30+) to retrieve crash reports\n * from previous sessions. Captures:\n * - CRASH: Java/Kotlin exception crashes\n * - CRASH_NATIVE: Native (NDK) crashes\n * - LOW_MEMORY: App killed due to low memory\n * - EXCESSIVE_RESOURCE_USAGE: App killed due to excessive resource usage\n *\n * ANRs are reported separately by ANRInstrumentation, not via ApplicationExitInfo replay.\n */\nexport class AndroidCrashReportingInstrumentation extends BaseCrashReportingInstrumentation {\n readonly name = '@grafana/faro-react-native:instrumentation-crash-android';\n readonly version = VERSION;\n\n protected parseCrashTrace(trace: string): ParsedAndroidCrashTrace | null {\n return parseAndroidCrashTrace(trace, {\n releaseBundleFilename: this.options.releaseBundleFilename,\n });\n }\n\n protected resolveCrashErrorMessage(crash: CrashReport, parsedTrace: ParsedAndroidCrashTrace | null): string {\n return resolveCrashErrorMessage(crash, parsedTrace);\n }\n\n protected shouldSkipCrashReport(crash: CrashReport): boolean {\n return shouldSkipCrashReport(crash);\n }\n\n protected getStackFrames(parsedTrace: ParsedAndroidCrashTrace | null): any[] {\n if (!parsedTrace) {\n return [];\n }\n // Android has JS frames, Java/Kotlin frames (R8 retrace), and NDK tombstone rows (.so retrace).\n return [...(parsedTrace.jsFrames ?? []), ...(parsedTrace.frames ?? []), ...(parsedTrace.nativeFrames ?? [])];\n }\n\n protected buildPlatformContext(parsedTrace: ParsedAndroidCrashTrace | null, context: Record<string, string>): void {\n // Store the native Java/Kotlin exception class separately for drill-down\n // Plugin overview metrics key off exception_type = 'crash', so keep that stable\n if (parsedTrace?.exceptionType) {\n context['nativeExceptionType'] = parsedTrace.exceptionType;\n }\n }\n\n protected getParseFailureWarning(): string {\n return 'Native crash trace present but no frames parsed; check Android trace format or UncaughtExceptionHandler cache';\n }\n\n protected getTraceUnavailableWarning(): string {\n return 'Native crash trace unavailable (ApplicationExitInfo traceInputStream was null at crash time)';\n }\n}\n"]}