Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# Changelog

## 0.22.0
## Unreleased

โš ๏ธ This release will affect issue grouping for iOS events as Sentry now captures correct stacktraces for manually captured and crashed iOS events.

### Features

- Improve iOS crash reports by adding scope data ([#491](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/491))
- โš ๏ธ This change will most likely affect issue grouping as Sentry now properly symbolicates Kotlin iOS crashes
- Improve stacktrace of manually captured exceptions on iOS ([#493](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/493))

## 0.22.0

### Features

### Dependencies

Expand Down Expand Up @@ -169,13 +175,15 @@ Potentially breaking: this release bumps the used Kotlin version to `2.1.21`.
### Features

- Add experimental session replay options to common code ([#275](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/275))

```kotlin
Sentry.init { options ->
// Adjust these values for production
options.sessionReplay.onErrorSampleRate = 1.0
options.sessionReplay.sessionSampleRate = 1.0
}
```

- Add `Sentry.isEnabled()` API to common code ([#273](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/273))
- Add `enableWatchdogTerminationTracking` in common options ([#281](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/281))
- Add `diagnosticLevel` in common options ([#287](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/287))
Expand Down Expand Up @@ -213,12 +221,13 @@ Sentry.init { options ->
- Enables auto installing of the required Sentry Cocoa SDK with Cocoapods (if Cocoapods plugin is enabled)
- Configures linking for SPM (needed if you want to compile a dynamic framework with `isStatic = false`)
- Configure via the `sentryKmp` configuration block in your build file

```kotlin
// Example configuration in build.gradle.kts
sentryKmp {
// Disable auto installing the KMP SDK to commonMain
autoInstall.commonMain.enabled = false
}
}
```

### Dependencies
Expand All @@ -236,7 +245,7 @@ sentryKmp {
### Features

- New Sentry KMP Gradle plugin ([#230](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/230))
- Install via `plugins { id("io.sentry.kotlin.multiplatform.gradle") version "{version}" }`
- Install via `plugins { id("io.sentry.kotlin.multiplatform.gradle") version "{version}" }`
- Enables auto installing of the KMP SDK to commonMain (if all targets are supported)
- Enables auto installing of the required Sentry Cocoa SDK with Cocoapods (if Cocoapods plugin is enabled)
- Configures linking for SPM (needed if you want to compile a dynamic framework)
Expand Down Expand Up @@ -266,6 +275,7 @@ sentryKmp {
- This allows you to initialize the SDK with platform-specific options that may not be available in the common code of the KMP SDK yet.

Usage:

```kotlin
// build.gradle.kts
kotlin {
Expand All @@ -284,7 +294,7 @@ fun init() {
expect fun platformOptionsConfiguration(): PlatformOptionsConfiguration

// iOS
actual fun createPlatformOptions(): PlatformOptionsConfiguration = {
actual fun createPlatformOptions(): PlatformOptionsConfiguration = {
dsn = "your_dsn"
release = "1.0.0"
// ...
Expand Down Expand Up @@ -366,8 +376,8 @@ pod("Sentry") {
- [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#710)
- [diff](https://github.com/getsentry/sentry-java/compare/6.33.1...7.1.0)
- Bump Cocoa SDK from v8.4.0 to v8.17.1 ([#158](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/163))
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8172)
- [diff](https://github.com/getsentry/sentry-cocoa/compare/8.4.0...8.17.2)
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8172)
- [diff](https://github.com/getsentry/sentry-cocoa/compare/8.4.0...8.17.2)
- Bump Kotlin version from v1.8.0 to v1.9.21 ([#146](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/146)

## 0.3.0
Expand Down Expand Up @@ -405,7 +415,7 @@ pod("Sentry") {

## 0.1.1

### Fixes
### Fixes

- fix: beforeSend dropping events if not set in options ([#79](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/79))

Expand Down Expand Up @@ -442,15 +452,14 @@ pod("Sentry") {

### Features

- JVM, Android, iOS, macOS, watchOS, tvOS integration
- Sentry init and close
- Capture Message
- Capture Exception with proper stack traces
- Custom unhandled exception handler on Cocoa to properly catch crashes and the stacktrace
- Scope configuration globally and locally
- User Feedback
- Attachments to Scope
- Screenshots option for Android and iOS
- Add beforeBreadcrumb hook
- Kotlin Multiplatform Sample project

- JVM, Android, iOS, macOS, watchOS, tvOS integration
- Sentry init and close
- Capture Message
- Capture Exception with proper stack traces
- Custom unhandled exception handler on Cocoa to properly catch crashes and the stacktrace
- Scope configuration globally and locally
- User Feedback
- Attachments to Scope
- Screenshots option for Android and iOS
- Add beforeBreadcrumb hook
- Kotlin Multiplatform Sample project
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package io.sentry.kotlin.multiplatform

import Internal.Sentry.PrivateSentrySDKOnly
import Internal.Sentry.kSentryLevelError
import cocoapods.Sentry.SentrySDK
import io.sentry.kotlin.multiplatform.extensions.toCocoaBreadcrumb
import io.sentry.kotlin.multiplatform.extensions.toCocoaUser
import io.sentry.kotlin.multiplatform.extensions.toCocoaUserFeedback
import io.sentry.kotlin.multiplatform.nsexception.asNSException
import io.sentry.kotlin.multiplatform.nsexception.asSentryEvent
import io.sentry.kotlin.multiplatform.nsexception.dropKotlinCrashEvent
import io.sentry.kotlin.multiplatform.protocol.Breadcrumb
import io.sentry.kotlin.multiplatform.protocol.SentryId
Expand Down Expand Up @@ -75,15 +76,22 @@ internal actual class SentryBridge actual constructor(private val sentryInstance
}

actual fun captureException(throwable: Throwable): SentryId {
val cocoaSentryId = SentrySDK.captureException(throwable.asNSException(true))
val event = throwable.asSentryEvent(
level = kSentryLevelError,
isHandled = true,
markThreadAsCrashed = false
)
val cocoaSentryId = SentrySDK.captureEvent(event)
return SentryId(cocoaSentryId.toString())
}

actual fun captureException(throwable: Throwable, scopeCallback: ScopeCallback): SentryId {
val cocoaSentryId = SentrySDK.captureException(
throwable.asNSException(true),
configureScopeCallback(scopeCallback)
val event = throwable.asSentryEvent(
level = kSentryLevelError,
isHandled = true,
markThreadAsCrashed = false
)
val cocoaSentryId = SentrySDK.captureEvent(event, configureScopeCallback(scopeCallback))
return SentryId(cocoaSentryId.toString())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package io.sentry.kotlin.multiplatform.nsexception

import Internal.Sentry.NSExceptionKt_SentryCrashStackCursorFromNSException
import Internal.Sentry.kSentryLevelFatal
import io.sentry.kotlin.multiplatform.CocoaSentryLevel
import kotlinx.cinterop.invoke
import platform.Foundation.NSException
import platform.Foundation.NSNumber
Expand Down Expand Up @@ -96,19 +97,29 @@ private fun Throwable.asSentryEnvelope(): CocoapodsSentryEnvelope {

/**
* Converts `this` [Throwable] to a [cocoapods.Sentry.SentryEvent].
*
* @param level The Sentry level (e.g., kSentryLevelFatal for crashes, kSentryLevelError for handled)
* @param isHandled Whether this is a handled exception (false for crashes, true for captured exceptions)
* @param markThreadAsCrashed Whether to mark the current thread as crashed (true for crashes, false for handled)
*/
@Suppress("UnnecessaryOptInAnnotation")
private fun Throwable.asSentryEvent(): CocoapodsSentryEvent =
CocoapodsSentryEvent(kSentryLevelFatal).apply {
internal fun Throwable.asSentryEvent(
level: CocoaSentryLevel = kSentryLevelFatal,
isHandled: Boolean = false,
markThreadAsCrashed: Boolean = true
): CocoapodsSentryEvent =
CocoapodsSentryEvent(level).apply {
@Suppress("UNCHECKED_CAST")
val threads =
threadInspector?.getCurrentThreadsWithStackTrace() as List<CocoapodsSentryThread>?
this.threads = threads
val currentThread = threads?.firstOrNull { it.current?.boolValue ?: false }?.apply {
setCrashed(NSNumber(true))
// Crashed threads shouldn't have a stacktrace, the thread_id should be set on the exception instead
// https://develop.sentry.dev/sdk/event-payloads/threads/
stacktrace = null
if (markThreadAsCrashed) {
setCrashed(NSNumber(true))
// Crashed threads shouldn't have a stacktrace, the thread_id should be set on the exception instead
// https://develop.sentry.dev/sdk/event-payloads/threads/
stacktrace = null
}
}
debugMeta = threads?.let {
InternalSentryDependencyContainer.sharedInstance().debugImageProvider.getDebugImagesForThreads(
Expand All @@ -117,18 +128,19 @@ private fun Throwable.asSentryEvent(): CocoapodsSentryEvent =
}
exceptions = this@asSentryEvent
.let { throwable -> throwable.causes.asReversed() + throwable }
.map { it.asNSException().asSentryException(currentThread?.threadId) }
.map { it.asNSException().asSentryException(currentThread?.threadId, isHandled) }
}

/**
* Converts `this` [NSException] to a [io.sentry.kotlin.multiplatform.protocol.SentryException].
*/
private fun NSException.asSentryException(
threadId: NSNumber?
threadId: NSNumber?,
isHandled: Boolean = false
): CocoapodsSentryException = CocoapodsSentryException(reason ?: "", name ?: "Throwable").apply {
this.threadId = threadId
mechanism = CocoapodsSentryMechanism("generic").apply {
setHandled(NSNumber(false))
setHandled(NSNumber(isHandled))
}
stacktrace = threadInspector?.stacktraceBuilder?.let { stacktraceBuilder ->
val cursor = NSExceptionKt_SentryCrashStackCursorFromNSException(this@asSentryException)
Expand Down