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
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ android {

dependencies {
compile 'com.facebook.react:react-native:+'
compile 'io.sentry:sentry-android:1.0.0-beta'
compile 'io.sentry:sentry-android:1.0.0-beta2'
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static void convertAndCaptureReactNativeException(String title, ReadableN
EventBuilder eventBuilder = new EventBuilder()
.withLevel(Event.Level.FATAL)
.withSentryInterface(new ExceptionInterface(exceptions));
Sentry.capture(eventBuilder);
Sentry.capture(RNSentryModule.buildEvent(eventBuilder));
}

private static SentryStackTraceElement[] convertToNativeStacktrace(ReadableNativeArray stack) {
Expand Down
102 changes: 79 additions & 23 deletions android/src/main/java/io/sentry/RNSentryModule.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package io.sentry;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;

import com.facebook.react.ReactApplication;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
Expand All @@ -10,6 +15,7 @@
import com.facebook.react.bridge.ReadableNativeArray;
import com.facebook.react.bridge.ReadableNativeMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -31,14 +37,18 @@ public class RNSentryModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext;
private final ReactApplication reactApplication;

private static AndroidEventBuilderHelper androidHelper;
private static PackageInfo packageInfo;
final static Logger logger = Logger.getLogger("react-native-sentry");
private ReadableMap extra;
private ReadableMap tags;
private static WritableNativeMap extra;
private static ReadableMap tags;

public RNSentryModule(ReactApplicationContext reactContext, ReactApplication reactApplication) {
super(reactContext);
this.reactContext = reactContext;
this.reactApplication = reactApplication;
RNSentryModule.extra = new WritableNativeMap();
RNSentryModule.packageInfo = getPackageInfo(reactContext);
}

public ReactApplication getReactApplication() {
Expand All @@ -60,6 +70,7 @@ public Map<String, Object> getConstants() {
@ReactMethod
public void startWithDsnString(String dsnString) {
SentryClient sentryClient = Sentry.init(dsnString, new AndroidSentryClientFactory(this.getReactApplicationContext()));
androidHelper = new AndroidEventBuilderHelper(this.getReactApplicationContext());
sentryClient.addEventSendCallback(new EventSendCallback() {
@Override
public void onFailure(Event event, Exception exception) {
Expand All @@ -84,12 +95,18 @@ public void setLogLevel(int level) {

@ReactMethod
public void setExtra(ReadableMap extra) {
this.extra = extra;
RNSentryModule.extra.merge(extra);
}

@ReactMethod
public void addExtra(String key, String value) {
RNSentryModule.extra.putString(key, value);
logger.info(String.format("addExtra '%s' '%s'", key, value));
}

@ReactMethod
public void setTags(ReadableMap tags) {
this.tags = tags;
RNSentryModule.tags = tags;
}

@ReactMethod
Expand Down Expand Up @@ -128,7 +145,6 @@ public void captureBreadcrumb(ReadableMap breadcrumb) {
public void captureEvent(ReadableMap event) {
ReadableNativeMap castEvent = (ReadableNativeMap)event;
if (event.hasKey("message")) {
AndroidEventBuilderHelper helper = new AndroidEventBuilderHelper(this.getReactApplicationContext());
EventBuilder eventBuilder = new EventBuilder()
.withMessage(event.getString("message"))
.withLogger(event.getString("logger"))
Expand All @@ -144,34 +160,19 @@ public void captureEvent(ReadableMap event) {
eventBuilder.withSentryInterface(userInterface);
}

helper.helpBuildingEvent(eventBuilder);

if (this.extra != null) {
for (Map.Entry<String, Object> entry : ((ReadableNativeMap)this.extra).toHashMap().entrySet()) {
eventBuilder.withExtra(entry.getKey(), entry.getValue());
}
}

if (castEvent.hasKey("extra")) {
for (Map.Entry<String, Object> entry : castEvent.getMap("extra").toHashMap().entrySet()) {
eventBuilder.withExtra(entry.getKey(), entry.getValue());
}
}

if (this.tags != null) {
for (Map.Entry<String, Object> entry : ((ReadableNativeMap)this.tags).toHashMap().entrySet()) {
eventBuilder.withExtra(entry.getKey(), entry.getValue());
}
}

if (castEvent.hasKey("tags")) {
for (Map.Entry<String, Object> entry : castEvent.getMap("tags").toHashMap().entrySet()) {
eventBuilder.withTag(entry.getKey(), entry.getValue().toString());
}
}

Event builtEvent = eventBuilder.build();
Sentry.capture(builtEvent);
Sentry.capture(buildEvent(eventBuilder));
} else {
RNSentryExceptionsManagerModule.lastReceivedException = event;
if (this.getReactApplication().getReactNativeHost().getUseDeveloperSupport() == true) {
Expand All @@ -186,8 +187,8 @@ public void captureEvent(ReadableMap event) {
@ReactMethod
public void clearContext() {
Sentry.clearContext();
this.extra = null;
this.tags = null;
RNSentryModule.extra = new WritableNativeMap();
RNSentryModule.tags = null;
}

@ReactMethod
Expand All @@ -197,6 +198,61 @@ public void activateStacktraceMerging(Promise promise) {
promise.reject("Sentry", "Stacktrace merging not yet implemented");
}

public static Event buildEvent(EventBuilder eventBuilder) {
androidHelper.helpBuildingEvent(eventBuilder);

setRelease(eventBuilder);
stripInternalSentry(eventBuilder);

if (extra != null) {
for (Map.Entry<String, Object> entry : extra.toHashMap().entrySet()) {
if (entry.getValue() != null) {
eventBuilder.withExtra(entry.getKey(), entry.getValue());
logger.info(String.format("addExtra '%s' '%s'", entry.getKey(), entry.getValue()));
}
}
}
if (tags != null) {
for (Map.Entry<String, Object> entry : ((ReadableNativeMap)tags).toHashMap().entrySet()) {
eventBuilder.withExtra(entry.getKey(), entry.getValue());
}
}

return eventBuilder.build();
}

private static void stripInternalSentry(EventBuilder eventBuilder) {
if (extra != null) {
for (Map.Entry<String, Object> entry : extra.toHashMap().entrySet()) {
if (entry.getKey().startsWith("__sentry")) {
extra.putNull(entry.getKey());
}
}
}
}

private static void setRelease(EventBuilder eventBuilder) {
if (extra.hasKey("__sentry_version")) {
eventBuilder.withRelease(packageInfo.packageName + "-" + extra.getString("__sentry_version"));
eventBuilder.withDist(null);
}
if (extra.hasKey("__sentry_release")) {
eventBuilder.withRelease(extra.getString("__sentry_release"));
}
if (extra.hasKey("__sentry_dist")) {
eventBuilder.withDist(extra.getString("__sentry_dist"));
}
}

private static PackageInfo getPackageInfo(Context ctx) {
try {
return ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
logger.info("Error getting package info.");
return null;
}
}

private Breadcrumb.Level breadcrumbLevel(String level) {
switch (level) {
case "critical":
Expand Down
18 changes: 18 additions & 0 deletions docs/codepush.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Using Sentry with CodePush
--------------------------

If you want to use sentry together with codepush you have to send us the codepush version::

.. sourcecode:: javascript

import CodePush from "react-native-code-push";

CodePush.getUpdateMetadata().then((update) => {
if (update) {
Sentry.setVersion('codepush:' + update.label);
}
});

Put this somewhere in you code where you already use codepush. This makes sure that we can
associate crashes with the right sourcemaps.
``Sentry.setVersion`` sets the the release to ``bundle_id-version`` this works for iOS aswell as Android.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Deep Dive

config
expo
codepush
sourcemaps
cocoapods
manual-setup
2 changes: 1 addition & 1 deletion examples/ReactNativeExample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"dependencies": {
"react": "^16.0.0-alpha.6",
"react-native": "^0.44.1",
"react-native": "^0.44.2",
"react-native-sentry": "file:../../"
}
}
2 changes: 1 addition & 1 deletion ios/Sentry
5 changes: 5 additions & 0 deletions lib/Sentry.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ export class Sentry {
Sentry._setInternalOption('dist', dist);
}

static setVersion(version) {
Sentry._setInternalOption('version', version);
}

// Private helpers

static _setInternalOption(key, value) {
Expand Down Expand Up @@ -301,6 +305,7 @@ class RavenClient {
data.dist = Sentry.options.internal['dist'];
}
});

Raven.config(dsn, this.options).install();
if (options.logLevel >= SentryLog.Debug) {
Raven.debug = true;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"glob": "7.1.1",
"inquirer": "3.0.6",
"raven-js": "^3.15.0",
"sentry-cli-binary": "^1.11.0",
"sentry-cli-binary": "^1.12.0",
"xcode": "0.9.3"
},
"rnpm": {
Expand Down