From cdcc8a024dfb4f6906e24ee318d9bf713ca444a9 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 29 May 2017 12:16:04 +0200 Subject: [PATCH 1/7] Initial support for codepush --- lib/Sentry.js | 1 + lib/codepush-plugin.js | 19 +++++++++++++++++++ package.json | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 lib/codepush-plugin.js diff --git a/lib/Sentry.js b/lib/Sentry.js index ee99b545a5..d971c3c09a 100644 --- a/lib/Sentry.js +++ b/lib/Sentry.js @@ -270,6 +270,7 @@ class RavenClient { Raven.addPlugin(require('./raven-plugin'), { 'nativeClientAvailable': Sentry.isNativeClientAvailable() }); + Raven.addPlugin(require('./codepush-plugin')); Raven.config(dsn, this.options).install(); if (options.logLevel >= SentryLog.Debug) { Raven.debug = true; diff --git a/lib/codepush-plugin.js b/lib/codepush-plugin.js new file mode 100644 index 0000000000..d08af73994 --- /dev/null +++ b/lib/codepush-plugin.js @@ -0,0 +1,19 @@ +function codePushPlugin(Raven, options) { + let codepush; + try { + codepush = require('react-native-code-push'); + } catch (e) { + return; + } + + codepush.getUpdateMetadata().then((update) => { + if (update) { + Raven.setDataCallback(function(data) { + let extra = data.extra || (data.extra = {}); + extra.__sentryVersionOverride = 'codepush:' + update.label; + }); + } + }); +} + +module.exports = codePushPlugin; diff --git a/package.json b/package.json index fccf0651e0..0e27e540f6 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "glob": "7.1.1", "inquirer": "3.0.6", "raven-js": "^3.15.0", - "sentry-cli-binary": "^1.9.0", + "sentry-cli-binary": "^2.0.0", "xcode": "0.9.3" }, "rnpm": { From 408fd8de5fe22072abd912ecae300ac3fa3eee5b Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 30 May 2017 16:22:51 +0200 Subject: [PATCH 2/7] Remove codepush-plugin, Add docs --- docs/codepush.rst | 17 +++++++++++++++++ docs/index.rst | 1 + ios/Sentry | 2 +- lib/Sentry.js | 5 ++++- lib/codepush-plugin.js | 16 ---------------- package.json | 2 +- 6 files changed, 24 insertions(+), 19 deletions(-) create mode 100644 docs/codepush.rst delete mode 100644 lib/codepush-plugin.js diff --git a/docs/codepush.rst b/docs/codepush.rst new file mode 100644 index 0000000000..c97a308853 --- /dev/null +++ b/docs/codepush.rst @@ -0,0 +1,17 @@ +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('version', '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. diff --git a/docs/index.rst b/docs/index.rst index 0be7887663..dd1291e7a8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -100,6 +100,7 @@ Deep Dive config expo + codepush sourcemaps cocoapods manual-setup diff --git a/ios/Sentry b/ios/Sentry index 02c952e72d..e8ed69af8c 160000 --- a/ios/Sentry +++ b/ios/Sentry @@ -1 +1 @@ -Subproject commit 02c952e72deabf4b8ae8acce1f678c6fb5d0a38f +Subproject commit e8ed69af8cf4d1d56f7bbd918d6eb342214cae13 diff --git a/lib/Sentry.js b/lib/Sentry.js index d1ca8fb43b..eea7595f0a 100644 --- a/lib/Sentry.js +++ b/lib/Sentry.js @@ -166,6 +166,10 @@ export class Sentry { Sentry._setInternalOption('dist', dist); } + static setVersion(version) { + Sentry._setInternalOption('version', version); + } + // Private helpers static _setInternalOption(key, value) { @@ -301,7 +305,6 @@ class RavenClient { data.dist = Sentry.options.internal['dist']; } }); - Raven.addPlugin(require('./codepush-plugin'), {}, Sentry); Raven.config(dsn, this.options).install(); if (options.logLevel >= SentryLog.Debug) { diff --git a/lib/codepush-plugin.js b/lib/codepush-plugin.js deleted file mode 100644 index c7d259d5ab..0000000000 --- a/lib/codepush-plugin.js +++ /dev/null @@ -1,16 +0,0 @@ -function codePushPlugin(Raven, options, Sentry) { - let codepush; - try { - codepush = require('react-native-code-push'); - } catch (e) { - return; - } - - codepush.getUpdateMetadata().then((update) => { - if (update) { - Sentry._setInternalOption('version', 'codepush:' + update.label); - } - }); -} - -module.exports = codePushPlugin; diff --git a/package.json b/package.json index 0e27e540f6..baaf8a2fed 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "glob": "7.1.1", "inquirer": "3.0.6", "raven-js": "^3.15.0", - "sentry-cli-binary": "^2.0.0", + "sentry-cli-binary": "^1.11.0", "xcode": "0.9.3" }, "rnpm": { From 9a64eb919b22a0e33353567d228c36f18568506f Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 30 May 2017 16:50:42 +0200 Subject: [PATCH 3/7] Fix docs --- docs/codepush.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codepush.rst b/docs/codepush.rst index c97a308853..39b596e534 100644 --- a/docs/codepush.rst +++ b/docs/codepush.rst @@ -9,7 +9,7 @@ If you want to use sentry together with codepush you have to send us the codepus CodePush.getUpdateMetadata().then((update) => { if (update) { - Sentry.setVersion('version', 'codepush:' + update.label); + Sentry.setVersion('codepush:' + update.label); } }); From a3f280b52fdf85801a8bb168450a0f62ece08596 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Tue, 30 May 2017 16:51:44 +0200 Subject: [PATCH 4/7] Update to latest commit --- ios/Sentry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Sentry b/ios/Sentry index e8ed69af8c..dee410a3ca 160000 --- a/ios/Sentry +++ b/ios/Sentry @@ -1 +1 @@ -Subproject commit e8ed69af8cf4d1d56f7bbd918d6eb342214cae13 +Subproject commit dee410a3caf40c1fcc10eaa64e463cfb1065e4cd From 7e76d2243499fb6e216c31fd93abacd8a6e06197 Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 31 May 2017 10:59:03 +0200 Subject: [PATCH 5/7] Add support for android --- android/build.gradle | 2 +- .../RNSentryExceptionsManagerModule.java | 2 +- .../main/java/io/sentry/RNSentryModule.java | 102 ++++++++++++++---- docs/codepush.rst | 1 + examples/ReactNativeExample/package.json | 2 +- 5 files changed, 83 insertions(+), 26 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 402c794864..8cf376a54b 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -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' } \ No newline at end of file diff --git a/android/src/main/java/io/sentry/RNSentryExceptionsManagerModule.java b/android/src/main/java/io/sentry/RNSentryExceptionsManagerModule.java index 04f35cb5b9..b3f05774ad 100644 --- a/android/src/main/java/io/sentry/RNSentryExceptionsManagerModule.java +++ b/android/src/main/java/io/sentry/RNSentryExceptionsManagerModule.java @@ -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) { diff --git a/android/src/main/java/io/sentry/RNSentryModule.java b/android/src/main/java/io/sentry/RNSentryModule.java index c8b20d01f2..dd1e16a978 100644 --- a/android/src/main/java/io/sentry/RNSentryModule.java +++ b/android/src/main/java/io/sentry/RNSentryModule.java @@ -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; @@ -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; @@ -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() { @@ -60,6 +70,7 @@ public Map 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) { @@ -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 @@ -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")) @@ -144,34 +160,19 @@ public void captureEvent(ReadableMap event) { eventBuilder.withSentryInterface(userInterface); } - helper.helpBuildingEvent(eventBuilder); - - if (this.extra != null) { - for (Map.Entry entry : ((ReadableNativeMap)this.extra).toHashMap().entrySet()) { - eventBuilder.withExtra(entry.getKey(), entry.getValue()); - } - } - if (castEvent.hasKey("extra")) { for (Map.Entry entry : castEvent.getMap("extra").toHashMap().entrySet()) { eventBuilder.withExtra(entry.getKey(), entry.getValue()); } } - if (this.tags != null) { - for (Map.Entry entry : ((ReadableNativeMap)this.tags).toHashMap().entrySet()) { - eventBuilder.withExtra(entry.getKey(), entry.getValue()); - } - } - if (castEvent.hasKey("tags")) { for (Map.Entry 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) { @@ -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 @@ -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 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 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 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": diff --git a/docs/codepush.rst b/docs/codepush.rst index 39b596e534..b20e90cb96 100644 --- a/docs/codepush.rst +++ b/docs/codepush.rst @@ -15,3 +15,4 @@ If you want to use sentry together with codepush you have to send us the codepus 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. diff --git a/examples/ReactNativeExample/package.json b/examples/ReactNativeExample/package.json index 5de1421768..c361419936 100644 --- a/examples/ReactNativeExample/package.json +++ b/examples/ReactNativeExample/package.json @@ -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:../../" } } From 533d89249b45bb14387c8991c426e148cdd7550d Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 31 May 2017 11:24:45 +0200 Subject: [PATCH 6/7] Use latest commit of sentry-cocoa --- ios/Sentry | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Sentry b/ios/Sentry index dee410a3ca..315df59eca 160000 --- a/ios/Sentry +++ b/ios/Sentry @@ -1 +1 @@ -Subproject commit dee410a3caf40c1fcc10eaa64e463cfb1065e4cd +Subproject commit 315df59ecabc0c6a2240bb17cbd9f688fb352e71 From 5987dd977ed8e8fcec1e443c15d3c170aeed326e Mon Sep 17 00:00:00 2001 From: Daniel Griesser Date: Wed, 31 May 2017 11:26:26 +0200 Subject: [PATCH 7/7] Bump sentry-cli version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index baaf8a2fed..af944d3b06 100644 --- a/package.json +++ b/package.json @@ -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": {