Skip to content

Commit

Permalink
fix(sdk): Add event.origin and event.environment on unhandled exc…
Browse files Browse the repository at this point in the history
…eption (#3041)
  • Loading branch information
krystofwoldrich authored May 5, 2023
1 parent 58c6995 commit 5d0d7b3
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 352 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Fixes

- Fix `event.origin` and `event.environment` on unhandled exception ([#3041](https://github.com/getsentry/sentry-react-native/pull/3041))

## 5.4.1

### Fixes
Expand Down
33 changes: 33 additions & 0 deletions RNSentryTester/RNSentryTesterTests/RNSentry+initNativeSdk.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import <Sentry/SentryOptions.h>
#import <Sentry/SentryEvent.h>
#import "RNSentry.h"

@interface RNSentryInitNativeSdkTests : XCTestCase
Expand Down Expand Up @@ -134,4 +135,36 @@ - (void)testPassesErrorOnWrongDsn
XCTAssertNotNil(error, @"Did not created error on invalid dsn");
}

- (void)testEventFromSentryCocoaReactNativeHasOriginAndEnvironmentTags
{
RNSentry* rnSentry = [[RNSentry alloc] init];
SentryEvent* testEvent = [[SentryEvent alloc] init];
testEvent.sdk = @{
@"name": @"sentry.cocoa.react-native"
};

[rnSentry setEventOriginTag: testEvent];

XCTAssertEqual(testEvent.tags[@"event.origin"], @"ios");
XCTAssertEqual(testEvent.tags[@"event.environment"], @"native");
}

- (void)testEventFromSentryReactNativeOriginAndEnvironmentTagsAreOverwritten
{
RNSentry* rnSentry = [[RNSentry alloc] init];
SentryEvent* testEvent = [[SentryEvent alloc] init];
testEvent.sdk = @{
@"name": @"sentry.cocoa.react-native"
};
testEvent.tags = @{
@"event.origin": @"testEventOriginTag",
@"event.environment": @"testEventEnvironmentTag"
};

[rnSentry setEventOriginTag: testEvent];

XCTAssertEqual(testEvent.tags[@"event.origin"], @"ios");
XCTAssertEqual(testEvent.tags[@"event.environment"], @"native");
}

@end
12 changes: 6 additions & 6 deletions android/src/main/java/io/sentry/react/RNSentryModuleImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import android.util.SparseIntArray;

import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.core.app.FrameMetricsAggregator;

import com.facebook.react.bridge.Arguments;
Expand Down Expand Up @@ -69,6 +68,8 @@ public class RNSentryModuleImpl {

public static final String NAME = "RNSentry";

private static final String NATIVE_SDK_NAME = "sentry.native.android";
private static final String ANDROID_SDK_NAME = "sentry.java.android.react-native";
private static final ILogger logger = new AndroidLogger(NAME);
private static final BuildInfoProvider buildInfo = new BuildInfoProvider(logger);
private static final String modulesPath = "modules.json";
Expand Down Expand Up @@ -104,12 +105,11 @@ Activity getCurrentActivity() {

public void initNativeSdk(final ReadableMap rnOptions, Promise promise) {
SentryAndroid.init(this.getReactApplicationContext(), options -> {
@NonNull final String sdkName = "sentry.java.android.react-native";
@Nullable SdkVersion sdkVersion = options.getSdkVersion();
if (sdkVersion == null) {
sdkVersion = new SdkVersion(sdkName, BuildConfig.VERSION_NAME);
sdkVersion = new SdkVersion(ANDROID_SDK_NAME, BuildConfig.VERSION_NAME);
} else {
sdkVersion.setName(sdkName);
sdkVersion.setName(ANDROID_SDK_NAME);
}

options.setSentryClientName(sdkVersion.getName() + "/" + sdkVersion.getVersion());
Expand Down Expand Up @@ -621,10 +621,10 @@ private void setEventOriginTag(SentryEvent event) {
switch (sdk.getName()) {
// If the event is from capacitor js, it gets set there and we do not handle it
// here.
case "sentry.native":
case NATIVE_SDK_NAME:
setEventEnvironmentTag(event, "native");
break;
case "sentry.java.android":
case ANDROID_SDK_NAME:
setEventEnvironmentTag(event, "java");
break;
default:
Expand Down
2 changes: 2 additions & 0 deletions ios/RNSentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
- (SentryOptions *_Nullable)createOptionsWithDictionary:(NSDictionary *_Nonnull)options
error:(NSError *_Nullable*_Nonnull)errorPointer;

- (void)setEventOriginTag:(SentryEvent *)event;

@end
11 changes: 6 additions & 5 deletions ios/RNSentry.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ + (void)storeEnvelope:(SentryEnvelope *)envelope;

static bool didFetchAppStart;

static NSString* const nativeSdkName = @"sentry.cocoa.react-native";

@implementation RNSentry {
bool sentHybridSdkDidBecomeActive;
}
Expand All @@ -56,9 +58,8 @@ + (BOOL)requiresMainQueueSetup {
return;
}

NSString *sdkName = @"sentry.cocoa.react-native";
NSString *sdkVersion = [PrivateSentrySDKOnly getSdkVersionString];
[PrivateSentrySDKOnly setSdkName: sdkName andVersionString: sdkVersion];
[PrivateSentrySDKOnly setSdkName: nativeSdkName andVersionString: sdkVersion];

[SentrySDK startWithOptions:sentryOptions];

Expand Down Expand Up @@ -137,9 +138,9 @@ - (void)setEventOriginTag:(SentryEvent *)event {
if (event.sdk != nil) {
NSString *sdkName = event.sdk[@"name"];

// If the event is from react native, it gets set there and we do not handle
// it here.
if ([sdkName isEqualToString:@"sentry.cocoa"]) {
// If the event is from react native, it gets set
// there and we do not handle it here.
if ([sdkName isEqual:nativeSdkName]) {
[self setEventEnvironmentTag:event origin:@"ios" environment:@"native"];
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"jest-environment-jsdom": "^29.4.1",
"prettier": "^2.0.5",
"react": "18.2.0",
"react-native": "0.71.0",
"react-native": "0.71.7",
"replace-in-file": "^6.0.0",
"rimraf": "^4.1.1",
"ts-jest": "^29.0.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,30 @@
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import io.sentry.ILogger;
import io.sentry.SentryLevel;
import io.sentry.android.core.AndroidLogger;

public class SamplePackage implements ReactPackage {

private static final ILogger logger = new AndroidLogger("SamplePackage");

static {
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
System.loadLibrary("appmodules");
}
}

public native void crash();

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
Expand All @@ -22,6 +38,20 @@ public List<NativeModule> createNativeModules(

modules.add(new AssetsModule(reactContext));

modules.add(new ReactContextBaseJavaModule() {
@Override public String getName() {
return "CppModule";
}

@ReactMethod public void crashCpp() {
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
crash();
} else {
logger.log(SentryLevel.WARNING, "Enable RNNA to try this.");
}
}
});

return modules;
}

Expand Down
7 changes: 7 additions & 0 deletions sample-new-architecture/android/app/src/main/jni/OnLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,10 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
&facebook::react::registerComponents;
});
}

extern "C"
JNIEXPORT void JNICALL
Java_com_samplenewarchitecture_SamplePackage_crash(JNIEnv *env, jobject thiz) {
char *ptr = 0;
*ptr += 1;
}
12 changes: 10 additions & 2 deletions sample-new-architecture/src/Screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ButtonProps,
StyleSheet,
NativeModules,
Platform,
} from 'react-native';

import * as Sentry from '@sentry/react-native';
Expand All @@ -19,7 +20,7 @@ import { UserFeedbackModal } from '../components/UserFeedbackModal';
import { FallbackRender } from '@sentry/react';
import NativeSampleModule from '../../tm/NativeSampleModule';

const { AssetsModule } = NativeModules;
const { AssetsModule, CppModule } = NativeModules;

interface Props {
navigation: StackNavigationProp<any, 'HomeScreen'>;
Expand Down Expand Up @@ -118,7 +119,14 @@ const HomeScreen = (props: Props) => {
NativeSampleModule?.crash();
}}
/>

{Platform.OS === 'android' && (
<Button
title="Crash in Android Cpp"
onPress={() => {
CppModule?.crashCpp();
}}
/>
)}
<Spacer />

<Sentry.ErrorBoundary fallback={errorBoundaryFallback}>
Expand Down
Loading

0 comments on commit 5d0d7b3

Please sign in to comment.