diff --git a/android/src/main/java/io/sentry/RNSentryModule.java b/android/src/main/java/io/sentry/RNSentryModule.java index 3dfbeb2a41..3903a1c2b7 100644 --- a/android/src/main/java/io/sentry/RNSentryModule.java +++ b/android/src/main/java/io/sentry/RNSentryModule.java @@ -7,7 +7,6 @@ import com.facebook.react.ReactApplication; import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; @@ -91,7 +90,7 @@ public Map getConstants() { } @ReactMethod - public void startWithDsnString(String dsnString, final ReadableMap options, Callback successCallback, Callback errorCallback) { + public void startWithDsnString(String dsnString, final ReadableMap options, Promise promise) { if (sentryClient != null) { logger.info(String.format("Already started, use existing client '%s'", dsnString)); return; @@ -101,7 +100,7 @@ public void startWithDsnString(String dsnString, final ReadableMap options, Call sentryClient = Sentry.init(dsnString, new AndroidSentryClientFactory(this.getReactApplicationContext())); } catch (Exception e) { logger.info(String.format("Catching on startWithDsnString, calling callback" + e.getMessage())); - errorCallback.invoke(e.getMessage()); + promise.reject("SentryError", "Error during init", e); return; } @@ -151,7 +150,7 @@ public boolean shouldSend(Event event) { } }); logger.info(String.format("startWithDsnString '%s'", dsnString)); - successCallback.invoke(); + promise.resolve(true); } @ReactMethod diff --git a/examples b/examples index d6c2dd55d4..4c2b7b1192 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit d6c2dd55d4822d1219b2c0abad7e5d59124ff597 +Subproject commit 4c2b7b1192566f7c1d9c6ce52a825a4116ba460e diff --git a/ios/RNSentry.m b/ios/RNSentry.m index a694992e0d..8d7a139963 100644 --- a/ios/RNSentry.m +++ b/ios/RNSentry.m @@ -125,7 +125,10 @@ - (void)setReleaseVersionDist:(SentryEvent *)event { resolve(crashedLastLaunch); } -RCT_EXPORT_METHOD(startWithDsnString:(NSString * _Nonnull)dsnString options:(NSDictionary *_Nonnull)options) +RCT_EXPORT_METHOD(startWithDsnString:(NSString * _Nonnull)dsnString + options:(NSDictionary *_Nonnull)options + resolve:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSError *error = nil; self.moduleMapping = [[NSMutableDictionary alloc] init]; @@ -152,7 +155,10 @@ - (void)setReleaseVersionDist:(SentryEvent *)event { [SentryClient.sharedClient startCrashHandlerWithError:&error]; if (error) { [NSException raise:@"SentryReactNative" format:@"%@", error.localizedDescription]; + reject(@"SentryReactNative", error.localizedDescription, error); + return; } + resolve(@YES); } RCT_EXPORT_METHOD(activateStacktraceMerging:(RCTPromiseResolveBlock)resolve diff --git a/lib/NativeClient.js b/lib/NativeClient.js index ac2213f983..c792536154 100644 --- a/lib/NativeClient.js +++ b/lib/NativeClient.js @@ -56,14 +56,8 @@ export class NativeClient { Object.assign(this.options, options); } - async customInit() { - return new Promise((resolve, reject) => { - RNSentry.startWithDsnString(this._dsn, this.options, () => { - resolve(); - }, (err) => { - reject(err); - }); - + async install() { + return RNSentry.startWithDsnString(this._dsn, this.options).then(() => { if (this.options.deactivateStacktraceMerging === false) { this._activateStacktraceMerging(); const eventEmitter = new NativeEventEmitter(RNSentryEventEmitter); @@ -77,28 +71,32 @@ export class NativeClient { } }); } - RNSentry.setLogLevel(options.logLevel); + RNSentry.setLogLevel(this.options.logLevel); }); } + _cloneObject(obj) { + return JSON.parse(JSON.stringify(obj)); + } + nativeCrash() { RNSentry.crash(); } captureEvent(event) { - RNSentry.captureEvent(event); + RNSentry.captureEvent(this._cloneObject(event)); } setUserContext(user) { - RNSentry.setUser(user); + RNSentry.setUser(this._cloneObject(user)); } setTagsContext(tags) { - RNSentry.setTags(tags); + RNSentry.setTags(this._cloneObject(tags)); } setExtraContext(extra) { - RNSentry.setExtra(extra); + RNSentry.setExtra(this._cloneObject(extra)); } addExtraContext(key, value) { @@ -106,7 +104,7 @@ export class NativeClient { } captureBreadcrumb(breadcrumb) { - RNSentry.captureBreadcrumb(breadcrumb); + RNSentry.captureBreadcrumb(this._cloneObject(breadcrumb)); } clearContext() { diff --git a/lib/Sentry.js b/lib/Sentry.js index f61e56de6a..a72aeae0ea 100644 --- a/lib/Sentry.js +++ b/lib/Sentry.js @@ -21,7 +21,7 @@ export const SentryLog = { }; export const Sentry = { - async install() { + install() { // We have to first setup raven otherwise react-native will freeze the options // and some properties like ignoreErrors can not be mutated by raven-js Sentry._ravenClient = new RavenClient(Sentry._dsn, Sentry.options); @@ -31,7 +31,6 @@ export const Sentry = { Sentry.options.disableNativeIntegration === false ) { Sentry._nativeClient = new NativeClient(Sentry._dsn, Sentry.options); - await Sentry._nativeClient.customInit(); Sentry.eventEmitter = new NativeEventEmitter(RNSentryEventEmitter); Sentry.eventEmitter.addListener( RNSentryEventEmitter.EVENT_SENT_SUCCESSFULLY, @@ -44,9 +43,20 @@ export const Sentry = { if (Sentry._internalEventStored) Sentry._internalEventStored(); }); } - // We need to call install here since this add the callback for sending events - // over the native bridge - Sentry._ravenClient.install(); + if (Sentry._nativeClient) { + Sentry._nativeClient + .install() + .then(() => { + Sentry._ravenClient.install(); + }) + .catch(error => { + throw error; + }); + } else { + // We need to call install here since this add the callback for sending events + // over the native bridge + Sentry._ravenClient.install(); + } }, config(dsn, options) {