Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Capture app start errors before JS #4472

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
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
54 changes: 53 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,59 @@
> make sure you follow our [migration guide](https://docs.sentry.io/platforms/react-native/migration/) first.
<!-- prettier-ignore-end -->

## Unreleased
## 6.7.0-alpha.0

### Features

- Capture App Start errors and crashes by initializing Sentry from `sentry.options.json` ([#4472](https://github.com/getsentry/sentry-react-native/pull/4472))

Create `sentry.options.json` in the React Native project root and set options the same as you currently have in `Sentry.init` in JS.

```json
{
"dsn": "https://[email protected]/value",
}
```

Initialize Sentry on the native layers by newly provided native methods.

```kotlin
import io.sentry.react.RNSentrySDK

class MainApplication : Application(), ReactApplication {
override fun onCreate() {
super.onCreate()
RNSentrySDK.init(this)
}
}
```

```obj-c
#import <RNSentry/RNSentry.h>

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[RNSentrySDK start];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
```

### Changes

- Load `optionsFile` into the JS bundle during Metro bundle process ([#4476](https://github.com/getsentry/sentry-react-native/pull/4476))
- Add experimental version of `startWithConfigureOptions` for Apple platforms ([#4444](https://github.com/getsentry/sentry-react-native/pull/4444))
- Add experimental version of `init` with optional `OptionsConfiguration<SentryAndroidOptions>` for Android ([#4451](https://github.com/getsentry/sentry-react-native/pull/4451))
- Add initialization using `sentry.options.json` for Apple platforms ([#4447](https://github.com/getsentry/sentry-react-native/pull/4447))
- Add initialization using `sentry.options.json` for Android ([#4451](https://github.com/getsentry/sentry-react-native/pull/4451))
- Merge options from file with `Sentry.init` options in JS ([#4510](https://github.com/getsentry/sentry-react-native/pull/4510))

### Internal

- Extract iOS native initialization to standalone structures ([#4442](https://github.com/getsentry/sentry-react-native/pull/4442))
- Extract Android native initialization to standalone structures ([#4445](https://github.com/getsentry/sentry-react-native/pull/4445))

### Dependencies

Expand Down
4 changes: 2 additions & 2 deletions dev-packages/e2e-tests/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sentry-react-native-e2e-tests",
"version": "6.6.0",
"version": "6.7.0-alpha.0",
"private": true,
"description": "Sentry React Native End to End Tests Library",
"main": "dist/index.js",
Expand All @@ -14,7 +14,7 @@
"@babel/preset-env": "^7.25.3",
"@babel/preset-typescript": "^7.18.6",
"@sentry/core": "8.54.0",
"@sentry/react-native": "6.6.0",
"@sentry/react-native": "6.7.0-alpha.0",
"@types/node": "^20.9.3",
"@types/react": "^18.2.64",
"appium": "2.4.1",
Expand Down
2 changes: 1 addition & 1 deletion dev-packages/type-check/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sentry-react-native-type-check",
"private": true,
"version": "6.6.0",
"version": "6.7.0-alpha.0",
"scripts": {
"type-check": "./run-type-check.sh"
}
Expand Down
2 changes: 1 addition & 1 deletion dev-packages/utils/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sentry-react-native-samples-utils",
"version": "6.6.0",
"version": "6.7.0-alpha.0",
"description": "Internal Samples Utils",
"main": "index.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "6.6.0",
"version": "6.7.0-alpha.0",
"packages": [
"packages/*",
"dev-packages/*",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/RNSentry.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Pod::Spec.new do |s|
s.preserve_paths = '*.js'

s.source_files = 'ios/**/*.{h,m,mm}'
s.public_header_files = 'ios/RNSentry.h'
s.public_header_files = 'ios/RNSentry.h', 'ios/RNSentrySDK.h'

s.compiler_flags = other_cflags

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"dsn": "invalid-dsn"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
invalid-options
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dsn": "https://[email protected]/123456",
"enableTracing": true,
"tracesSampleRate": 1.0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package io.sentry.react

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import io.sentry.react.RNSentryJsonConverter.convertToWritable
import org.json.JSONArray
import org.json.JSONObject
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class RNSentryJsonConverterTest {
@Test
fun testConvertToWritableWithSimpleJsonObject() {
val jsonObject =
JSONObject().apply {
put("floatKey", 12.3f)
put("doubleKey", 12.3)
put("intKey", 123)
put("stringKey", "test")
put("nullKey", JSONObject.NULL)
}

val result: WritableMap? = convertToWritable(jsonObject)

assertNotNull(result)
assertEquals(12.3, result!!.getDouble("floatKey"), 0.0001)
assertEquals(12.3, result.getDouble("doubleKey"), 0.0)
assertEquals(123, result.getInt("intKey"))
assertEquals("test", result.getString("stringKey"))
assertNull(result.getString("nullKey"))
}

@Test
fun testConvertToWritableWithNestedJsonObject() {
val jsonObject =
JSONObject().apply {
put(
"nested",
JSONObject().apply {
put("key", "value")
},
)
}

val result: WritableMap? = convertToWritable(jsonObject)

assertNotNull(result)
val nestedMap = result!!.getMap("nested")
assertNotNull(nestedMap)
assertEquals("value", nestedMap!!.getString("key"))
}

@Test
fun testConvertToWritableWithJsonArray() {
val jsonArray =
JSONArray().apply {
put(1)
put(2.5)
put("string")
put(JSONObject.NULL)
}

val result: WritableArray = convertToWritable(jsonArray)

assertEquals(1, result.getInt(0))
assertEquals(2.5, result.getDouble(1), 0.0)
assertEquals("string", result.getString(2))
assertNull(result.getString(3))
}

@Test
fun testConvertToWritableWithNestedJsonArray() {
val jsonObject =
JSONObject().apply {
put(
"array",
JSONArray().apply {
put(
JSONObject().apply {
put("key1", "value1")
},
)
put(
JSONObject().apply {
put("key2", "value2")
},
)
},
)
}

val result: WritableMap? = convertToWritable(jsonObject)

val array = result?.getArray("array")
assertEquals("value1", array?.getMap(0)?.getString("key1"))
assertEquals("value2", array?.getMap(1)?.getString("key2"))
}
}
Loading
Loading