1414
1515package io.sentry.kotlin.multiplatform.nsexception
1616
17- import NSException.Sentry.NSExceptionKt_SentryCrashStackCursorFromNSException
18- import NSException.Sentry.NSExceptionKt_SentryMechanismSetNotHandled
19- import NSException.Sentry.NSExceptionKt_SentryThreadSetCrashed
20- import NSException.Sentry.SentryDependencyContainer
21- import NSException.Sentry.SentryEnvelope
22- import NSException.Sentry.SentryEnvelopeHeader
23- import NSException.Sentry.SentryEnvelopeItem
24- import NSException.Sentry.SentryEvent
25- import NSException.Sentry.SentryException
26- import NSException.Sentry.SentryMechanism
27- import NSException.Sentry.SentrySDK
28- import NSException.Sentry.SentryThread
29- import NSException.Sentry.SentryThreadInspector
30- import NSException.Sentry.currentHub
31- import NSException.Sentry.isCrashEvent
32- import NSException.Sentry.kSentryLevelFatal
33- import NSException.Sentry.prepareEvent
34- import NSException.Sentry.storeEnvelope
35- import NSException.Sentry.threadInspector
17+ import Internal.Sentry.NSExceptionKt_SentryCrashStackCursorFromNSException
18+ import Internal.Sentry.kSentryLevelFatal
3619import platform.Foundation.NSException
3720import platform.Foundation.NSNumber
3821
22+ private typealias InternalSentryEvent = Internal .Sentry .SentryEvent
23+ private typealias InternalSentrySDK = Internal .Sentry .SentrySDK
24+ private typealias InternalSentryEnvelope = Internal .Sentry .SentryEnvelope
25+ private typealias InternalSentryDependencyContainer = Internal .Sentry .SentryDependencyContainer
26+ private typealias InternalSentryEnvelopeHeader = Internal .Sentry .SentryEnvelopeHeader
27+ private typealias InternalSentryEnvelopeItem = Internal .Sentry .SentryEnvelopeItem
28+ private typealias InternalSentryThreadInspector = Internal .Sentry .SentryThreadInspector
29+
30+ private typealias CocoapodsSentryEvent = cocoapods.Sentry .SentryEvent
31+ private typealias CocoapodsSentrySDK = cocoapods.Sentry .SentrySDK
32+ private typealias CocoapodsSentryStacktrace = cocoapods.Sentry .SentryStacktrace
33+ private typealias CocoapodsSentryException = cocoapods.Sentry .SentryException
34+ private typealias CocoapodsSentryMechanism = cocoapods.Sentry .SentryMechanism
35+ private typealias CocoapodsSentryThread = cocoapods.Sentry .SentryThread
36+
3937/* *
4038 * Drops the Kotlin crash that follows an unhandled Kotlin exception except our custom SentryEvent.
4139 */
42- internal fun dropKotlinCrashEvent (event : SentryEvent ? ): SentryEvent ? {
43- return event?.takeUnless { it.isCrashEvent && (it.tags?.containsKey(KOTLIN_CRASH_TAG ) ? : false ) }
40+ internal fun dropKotlinCrashEvent (event : CocoapodsSentryEvent ? ): CocoapodsSentryEvent ? {
41+ return event?.takeUnless {
42+ (it as InternalSentryEvent ).isCrashEvent && (
43+ it.tags?.containsKey(
44+ KOTLIN_CRASH_TAG
45+ ) ? : false
46+ )
47+ }
4448}
4549
4650/* *
@@ -53,8 +57,8 @@ public fun setSentryUnhandledExceptionHook(): Unit = wrapUnhandledExceptionHook
5357 val envelope = throwable.asSentryEnvelope()
5458 // The envelope will be persisted, so we can safely terminate afterwards.
5559 // https://github.com/getsentry/sentry-cocoa/blob/678172142ac1d10f5ed7978f69d16ab03e801057/Sources/Sentry/SentryClient.m#L409
56- SentrySDK .storeEnvelope(envelope)
57- SentrySDK .configureScope { scope ->
60+ InternalSentrySDK .storeEnvelope(envelope)
61+ CocoapodsSentrySDK .configureScope { scope ->
5862 scope?.setTagValue(KOTLIN_CRASH_TAG , KOTLIN_CRASH_TAG )
5963 }
6064}
@@ -67,56 +71,60 @@ internal const val KOTLIN_CRASH_TAG = "nsexceptionkt.kotlin_crashed"
6771/* *
6872 * Converts `this` [Throwable] to a [SentryEnvelope].
6973 */
70- internal fun Throwable.asSentryEnvelope (): SentryEnvelope {
71- val event = asSentryEvent()
72- val preparedEvent = SentrySDK .currentHub().let { hub ->
73- hub.getClient()?.prepareEvent(event, hub.scope, alwaysAttachStacktrace = false , isCrashEvent = true )
74+ internal fun Throwable.asSentryEnvelope (): InternalSentryEnvelope {
75+ val event = asSentryEvent() as InternalSentryEvent
76+ val preparedEvent = InternalSentrySDK .currentHub().let { hub ->
77+ hub.getClient()
78+ ?.prepareEvent(event, hub.scope, alwaysAttachStacktrace = false , isCrashEvent = true )
7479 } ? : event
75- val item = SentryEnvelopeItem (preparedEvent)
80+ val item = InternalSentryEnvelopeItem (preparedEvent)
7681 // TODO: pass traceState when enabling performance monitoring for KMP SDK
77- val header = SentryEnvelopeHeader (preparedEvent.eventId, null )
78- return SentryEnvelope (header, listOf (item))
82+ val header = InternalSentryEnvelopeHeader (preparedEvent.eventId, null )
83+ return InternalSentryEnvelope (header, listOf (item))
7984}
8085
8186/* *
8287 * Converts `this` [Throwable] to a [SentryEvent].
8388 */
8489@Suppress(" UnnecessaryOptInAnnotation" )
85- private fun Throwable.asSentryEvent (): SentryEvent = SentryEvent (kSentryLevelFatal).apply {
86- isCrashEvent = true
87- @Suppress(" UNCHECKED_CAST" )
88- val threads = threadInspector?.getCurrentThreadsWithStackTrace() as List <SentryThread >?
89- this .threads = threads
90- val currentThread = threads?.firstOrNull { it.current?.boolValue ? : false }?.apply {
91- NSExceptionKt_SentryThreadSetCrashed (this )
92- // Crashed threats shouldn't have a stacktrace, the thread_id should be set on the exception instead
93- // https://develop.sentry.dev/sdk/event-payloads/threads/
94- stacktrace = null
90+ private fun Throwable.asSentryEvent (): CocoapodsSentryEvent =
91+ CocoapodsSentryEvent (kSentryLevelFatal).apply {
92+ @Suppress(" UNCHECKED_CAST" )
93+ val threads =
94+ threadInspector?.getCurrentThreadsWithStackTrace() as List <CocoapodsSentryThread >?
95+ this .threads = threads
96+ val currentThread = threads?.firstOrNull { it.current?.boolValue ? : false }?.apply {
97+ setCrashed(NSNumber (true ))
98+ // Crashed threads shouldn't have a stacktrace, the thread_id should be set on the exception instead
99+ // https://develop.sentry.dev/sdk/event-payloads/threads/
100+ stacktrace = null
101+ }
102+ debugMeta = threads?.let {
103+ InternalSentryDependencyContainer .sharedInstance().debugImageProvider.getDebugImagesForThreads(
104+ it
105+ )
106+ }
107+ exceptions = this @asSentryEvent
108+ .let { throwable -> throwable.causes.asReversed() + throwable }
109+ .map { it.asNSException().asSentryException(currentThread?.threadId) }
95110 }
96- debugMeta = threads?.let {
97- SentryDependencyContainer .sharedInstance().debugImageProvider.getDebugImagesForThreads(it)
98- }
99- exceptions = this @asSentryEvent
100- .let { throwable -> throwable.causes.asReversed() + throwable }
101- .map { it.asNSException().asSentryException(currentThread?.threadId) }
102- }
103111
104112/* *
105113 * Converts `this` [NSException] to a [SentryException].
106114 */
107115private fun NSException.asSentryException (
108116 threadId : NSNumber ?
109- ): SentryException = SentryException (reason ? : " " , name ? : " Throwable" ).apply {
117+ ): CocoapodsSentryException = CocoapodsSentryException (reason ? : " " , name ? : " Throwable" ).apply {
110118 this .threadId = threadId
111- mechanism = SentryMechanism (" generic" ).apply {
112- NSExceptionKt_SentryMechanismSetNotHandled ( this )
119+ mechanism = CocoapodsSentryMechanism (" generic" ).apply {
120+ setHandled( NSNumber ( false ) )
113121 }
114122 stacktrace = threadInspector?.stacktraceBuilder?.let { stacktraceBuilder ->
115123 val cursor = NSExceptionKt_SentryCrashStackCursorFromNSException (this @asSentryException)
116124 val stacktrace = stacktraceBuilder.retrieveStacktraceFromCursor(cursor)
117- stacktrace
125+ stacktrace as CocoapodsSentryStacktrace
118126 }
119127}
120128
121- private val threadInspector: SentryThreadInspector ?
122- get() = SentrySDK .currentHub().getClient()?.threadInspector
129+ private val threadInspector: InternalSentryThreadInspector ?
130+ get() = InternalSentrySDK .currentHub().getClient()?.threadInspector
0 commit comments