@posthog/react-native-plugin 2.12.0 → 2.12.2
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.
package/android/build.gradle
CHANGED
|
@@ -91,7 +91,7 @@ dependencies {
|
|
|
91
91
|
//noinspection GradleDynamicVersion
|
|
92
92
|
implementation "com.facebook.react:react-native:+"
|
|
93
93
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
94
|
-
implementation "com.posthog:posthog-android:3.71.
|
|
94
|
+
implementation "com.posthog:posthog-android:3.71.2"
|
|
95
95
|
|
|
96
96
|
testImplementation "junit:junit:4.13.2"
|
|
97
97
|
testImplementation "org.json:json:20250517"
|
package/android/src/main/java/com/posthogreactnativeplugin/PosthogReactNativePluginModule.kt
CHANGED
|
@@ -17,6 +17,7 @@ import com.facebook.react.common.JavascriptException
|
|
|
17
17
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
18
18
|
import com.posthog.PostHog
|
|
19
19
|
import com.posthog.PostHogConfig
|
|
20
|
+
import com.posthog.PostHogEvent
|
|
20
21
|
import com.posthog.android.PostHogAndroid
|
|
21
22
|
import com.posthog.android.PostHogAndroidConfig
|
|
22
23
|
import com.posthog.android.replay.PostHogReplayIntegration
|
|
@@ -171,6 +172,7 @@ class PosthogReactNativePluginModule(
|
|
|
171
172
|
// React Native rethrows fatal JS errors natively as JavascriptException.
|
|
172
173
|
// The JS layer already captured them, so drop the native duplicate.
|
|
173
174
|
errorTrackingConfig.ignoredExceptionTypes.add(JavascriptException::class.java)
|
|
175
|
+
addBeforeSend { restoreJsFatalCaptureProperties(it) }
|
|
174
176
|
|
|
175
177
|
// Always apply the session replay configuration so that recording started later
|
|
176
178
|
// (e.g. startRecording or a linked feature flag) uses the right mode and masking;
|
|
@@ -456,12 +458,14 @@ class PosthogReactNativePluginModule(
|
|
|
456
458
|
// ReadableMap.toHashMap() is HashMap<String, Any?>; the native API takes Map<String, Any>?.
|
|
457
459
|
@Suppress("UNCHECKED_CAST")
|
|
458
460
|
val nativeProperties = properties.toHashMap() as Map<String, Any>
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
461
|
+
withJsFatalCaptureProperties(nativeProperties) {
|
|
462
|
+
PostHog.capture(
|
|
463
|
+
event = "\$exception",
|
|
464
|
+
distinctId = distinctId.takeIf { it.isNotEmpty() },
|
|
465
|
+
properties = nativeProperties,
|
|
466
|
+
timestamp = parsedTimestamp,
|
|
467
|
+
)
|
|
468
|
+
}
|
|
465
469
|
promise.resolve(null)
|
|
466
470
|
} catch (e: Throwable) {
|
|
467
471
|
logError("captureFatalException", e)
|
|
@@ -722,6 +726,49 @@ class PosthogReactNativePluginModule(
|
|
|
722
726
|
}
|
|
723
727
|
}
|
|
724
728
|
|
|
729
|
+
// posthog-android computes these from its own state, which JS never syncs (the app's
|
|
730
|
+
// `personProfiles` mode, identify, person processing started by `group()` and friends), and
|
|
731
|
+
// newer versions no longer let caller properties override them. JS decided them for its fatal
|
|
732
|
+
// crash, so its values stand.
|
|
733
|
+
private val JS_OWNED_FATAL_CAPTURE_KEYS = listOf("\$process_person_profile", "\$is_identified")
|
|
734
|
+
|
|
735
|
+
// Set only while the JS layer's own fatal capture runs; posthog-android runs `beforeSend`
|
|
736
|
+
// on the calling thread, so nothing else it emits sees these properties.
|
|
737
|
+
private val jsFatalCaptureProperties = ThreadLocal<Map<String, Any>?>()
|
|
738
|
+
|
|
739
|
+
internal fun <T> withJsFatalCaptureProperties(
|
|
740
|
+
properties: Map<String, Any>,
|
|
741
|
+
block: () -> T,
|
|
742
|
+
): T {
|
|
743
|
+
jsFatalCaptureProperties.set(properties)
|
|
744
|
+
try {
|
|
745
|
+
return block()
|
|
746
|
+
} finally {
|
|
747
|
+
jsFatalCaptureProperties.remove()
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
internal fun restoreJsFatalCaptureProperties(event: PostHogEvent): PostHogEvent {
|
|
752
|
+
val jsProperties = jsFatalCaptureProperties.get()
|
|
753
|
+
if (event.event != "\$exception" || jsProperties == null) {
|
|
754
|
+
return event
|
|
755
|
+
}
|
|
756
|
+
for (key in JS_OWNED_FATAL_CAPTURE_KEYS) {
|
|
757
|
+
if (!jsProperties.containsKey(key)) {
|
|
758
|
+
continue
|
|
759
|
+
}
|
|
760
|
+
// The JS map can hold nulls despite its type (`toHashMap()`); a null is omitted on the
|
|
761
|
+
// wire, so drop native's value rather than send it.
|
|
762
|
+
val value: Any? = jsProperties[key]
|
|
763
|
+
if (value == null) {
|
|
764
|
+
event.properties?.remove(key)
|
|
765
|
+
} else {
|
|
766
|
+
event.properties?.put(key, value)
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return event
|
|
770
|
+
}
|
|
771
|
+
|
|
725
772
|
// The JS layer sends an ISO-8601 UTC timestamp (`Date#toISOString`). Parse it explicitly
|
|
726
773
|
// rather than trusting a locale-dependent default, and treat anything unparseable as a
|
|
727
774
|
// caller error: silently substituting "now" would attribute the crash to the wrong instant.
|
|
@@ -274,9 +274,9 @@ public class PosthogReactNativePlugin: RCTEventEmitter {
|
|
|
274
274
|
// `buildProperties` keeps its own value on a key clash (`{ current, _ in
|
|
275
275
|
// current }`), so native's enrichment silently wins over what JS decided —
|
|
276
276
|
// `$process_person_profile` from `personProfiles: 'never'`, or any value the
|
|
277
|
-
// app's `before_send` rewrote. Put the JS-approved values back. Android
|
|
278
|
-
//
|
|
279
|
-
//
|
|
277
|
+
// app's `before_send` rewrote. Put the JS-approved values back. On Android,
|
|
278
|
+
// caller properties already win apart from SDK debug properties, so the
|
|
279
|
+
// module there only restores `$process_person_profile` and `$is_identified`.
|
|
280
280
|
for (key, value) in jsProperties {
|
|
281
281
|
event.properties[key] = value
|
|
282
282
|
}
|