diff --git a/docs/config.rst b/docs/config.rst index 87d8b3ab7b..04fa3dd755 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -15,7 +15,8 @@ These are functions you can call in your javascript code: Sentry.config("___DSN___", { deactivateStacktraceMerging: false, // default: true | Deactivates the stacktrace merging feature logLevel: SentryLog.Debug, // default SentryLog.None | Possible values: .None, .Error, .Debug, .Verbose - disableNativeIntegration: false // default: false | Deactivates the native integration and only uses raven-js + disableNativeIntegration: false, // default: false | Deactivates the native integration and only uses raven-js + handlePromiseRejection: true // default: true | Handle unhandled promise rejections // sampleRate: 0.5 // default: 1.0 | Only set this if you don't want to send every event so e.g.: 0.5 will send 50% of all events // These two options will only be considered if stacktrace merging is active // Here you can add modules that should be ignored or exclude modules diff --git a/lib/RavenClient.js b/lib/RavenClient.js index e93446e2e3..02b600eb57 100644 --- a/lib/RavenClient.js +++ b/lib/RavenClient.js @@ -31,7 +31,8 @@ export class RavenClient { Raven.addPlugin( require('./raven-plugin'), { - nativeClientAvailable: Sentry.isNativeClientAvailable() + nativeClientAvailable: Sentry.isNativeClientAvailable(), + handlePromiseRejection: this.options.handlePromiseRejection }, data => { if (Sentry.options.internal) { diff --git a/lib/Sentry.js b/lib/Sentry.js index a01a99d28e..97b1dc9956 100644 --- a/lib/Sentry.js +++ b/lib/Sentry.js @@ -56,7 +56,8 @@ export const Sentry = { Sentry.options = { logLevel: SentryLog.None, instrument: false, - disableNativeIntegration: false + disableNativeIntegration: false, + handlePromiseRejection: true }; Object.assign(Sentry.options, options); return Sentry; diff --git a/lib/raven-plugin.js b/lib/raven-plugin.js index 5dbeae41ef..7b3b371dd6 100644 --- a/lib/raven-plugin.js +++ b/lib/raven-plugin.js @@ -81,14 +81,17 @@ function reactNativePlugin(Raven, options, internalDataCallback) { Raven.setTransport(reactNativePlugin._transport); // Check for a previously persisted payload, and report it. - reactNativePlugin._restorePayload().then(function(payload) { - options.onInitialize && options.onInitialize(payload); - if (!payload) return; - Raven._sendProcessedPayload(payload, function(error) { - if (error) return; // Try again next launch. - reactNativePlugin._clearPayload(); - }); - })['catch'](function() {}); + reactNativePlugin + ._restorePayload() + .then(function(payload) { + options.onInitialize && options.onInitialize(payload); + if (!payload) return; + Raven._sendProcessedPayload(payload, function(error) { + if (error) return; // Try again next launch. + reactNativePlugin._clearPayload(); + }); + }) + ['catch'](function() {}); Raven.setShouldSendCallback(function(data, originalCallback) { if (!(FATAL_ERROR_KEY in data)) { @@ -99,11 +102,14 @@ function reactNativePlugin(Raven, options, internalDataCallback) { var origError = data[FATAL_ERROR_KEY]; delete data[FATAL_ERROR_KEY]; - reactNativePlugin._persistPayload(data).then(function() { - defaultHandler(origError, true); - handlingFatal = false; // In case it isn't configured to crash. - return null; - })['catch'](function() {}); + reactNativePlugin + ._persistPayload(data) + .then(function() { + defaultHandler(origError, true); + handlingFatal = false; // In case it isn't configured to crash. + return null; + }) + ['catch'](function() {}); return false; // Do not continue. }); @@ -119,20 +125,22 @@ function reactNativePlugin(Raven, options, internalDataCallback) { (ErrorUtils.getGlobalHandler && ErrorUtils.getGlobalHandler()) || ErrorUtils._globalHandler; - // Track unhandled promise rejections - var tracking = require('promise/setimmediate/rejection-tracking'); - tracking.disable(); - tracking.enable({ - allRejections: true, - onUnhandled: function(id, error) { - var captureOptions = { - timestamp: new Date() / 1000, - type: 'Unhandled Promise Rejection' - }; - Raven.captureException(error, captureOptions); - }, - onHandled: function() {} - }); + if (options.handlePromiseRejection) { + // Track unhandled promise rejections + var tracking = require('promise/setimmediate/rejection-tracking'); + tracking.disable(); + tracking.enable({ + allRejections: true, + onUnhandled: function(id, error) { + var captureOptions = { + timestamp: new Date() / 1000, + type: 'Unhandled Promise Rejection' + }; + Raven.captureException(error, captureOptions); + }, + onHandled: function() {} + }); + } ErrorUtils.setGlobalHandler(function(error, isFatal) { var captureOptions = { @@ -189,11 +197,13 @@ reactNativePlugin._persistPayload = function(payload) { */ reactNativePlugin._restorePayload = function() { var AsyncStorage = require('react-native').AsyncStorage; - var promise = AsyncStorage.getItem(ASYNC_STORAGE_KEY).then(function(payload) { - return JSON.parse(payload); - })['catch'](function() { - return null; - }); + var promise = AsyncStorage.getItem(ASYNC_STORAGE_KEY) + .then(function(payload) { + return JSON.parse(payload); + }) + ['catch'](function() { + return null; + }); // Make sure that we fetch ASAP. var RCTAsyncSQLiteStorage = NativeModules.AsyncSQLiteDBStorage; var RCTAsyncRocksDBStorage = NativeModules.AsyncRocksDBStorage;