From 8ad7cd08baec248fd88c01dccc460e0c156cb18f Mon Sep 17 00:00:00 2001 From: Ian MacLeod Date: Tue, 31 May 2016 10:04:42 -0700 Subject: [PATCH] Support for a custom URI normalization function when reporting react native asset paths You can now pass `normalizeUrl` as an argument when initializing the react native plugin. It is a function that returns the normalized path for use when retrieving release assets. --- plugins/react-native.js | 40 ++++++++++++++++--------------- test/plugins/react-native.test.js | 10 ++++---- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/plugins/react-native.js b/plugins/react-native.js index 4db0644cd512..cabbb2136030 100644 --- a/plugins/react-native.js +++ b/plugins/react-native.js @@ -12,19 +12,13 @@ * pathStrip: A RegExp that matches the portions of a file URI that should be * removed from stacks prior to submission. * + * normalizeUrl: A function that is given the file:// URI to a bundle, and + * should return its normalized form (used for release asset lookup). + * */ 'use strict'; -var PATH_STRIP_RE = /^\/var\/mobile\/Containers\/Bundle\/Application\/[^\/]+\/[^\.]+\.app/; - -/** - * Strip device-specific IDs from React Native file:// paths - */ -function normalizeUrl(url, pathStripRe) { - return url - .replace(/^file\:\/\//, '') - .replace(pathStripRe, ''); -} +var DEFAULT_PATH_STRIP_RE = /^\/var\/mobile\/Containers\/Bundle\/Application\/[^\/]+\/[^\.]+\.app/; /** * Extract key/value pairs from an object and encode them for @@ -44,6 +38,18 @@ function urlencode(obj) { */ function reactNativePlugin(Raven, options) { options = options || {}; + if (options.pathStrip && options.normalizeUrl) { + throw new TypeError('Please pass either pathStrip or normalizeUrl, not both'); + } + var normalizeUrl = options.normalizeUrl; + if (!normalizeUrl) { + var pathStripRe = options.pathStripRe || DEFAULT_PATH_STRIP_RE; + normalizeUrl = function defaultNormalizeUrl(url) { + return url + .replace(/^file\:\/\//, '') + .replace(pathStripRe, ''); + }; + } // react-native doesn't have a document, so can't use default Image // transport - use XMLHttpRequest instead @@ -51,14 +57,14 @@ function reactNativePlugin(Raven, options) { // Use data callback to strip device-specific paths from stack traces Raven.setDataCallback(function(data) { - reactNativePlugin._normalizeData(data, options.pathStrip) + reactNativePlugin._normalizeData(data, normalizeUrl); }); var defaultHandler = ErrorUtils.getGlobalHandler && ErrorUtils.getGlobalHandler() || ErrorUtils._globalHandler; ErrorUtils.setGlobalHandler(function() { var error = arguments[0]; - defaultHandler.apply(this, arguments) + defaultHandler.apply(this, arguments); Raven.captureException(error); }); } @@ -102,19 +108,15 @@ reactNativePlugin._transport = function (options) { * Strip device-specific IDs found in culprit and frame filenames * when running React Native applications on a physical device. */ -reactNativePlugin._normalizeData = function (data, pathStripRe) { - if (!pathStripRe) { - pathStripRe = PATH_STRIP_RE; - } - +reactNativePlugin._normalizeData = function (data, normalizeUrl) { if (data.culprit) { - data.culprit = normalizeUrl(data.culprit, pathStripRe); + data.culprit = normalizeUrl(data.culprit); } if (data.exception) { // if data.exception exists, all of the other keys are guaranteed to exist data.exception.values[0].stacktrace.frames.forEach(function (frame) { - frame.filename = normalizeUrl(frame.filename, pathStripRe); + frame.filename = normalizeUrl(frame.filename); }); } }; diff --git a/test/plugins/react-native.test.js b/test/plugins/react-native.test.js index 62a205bb8f1f..f502b310c9b8 100644 --- a/test/plugins/react-native.test.js +++ b/test/plugins/react-native.test.js @@ -39,12 +39,14 @@ describe('React Native plugin', function () { }], } }; - reactNativePlugin._normalizeData(data); + reactNativePlugin._normalizeData(data, function(uri) { + return uri.replace(/^.*\//, ''); + }); - assert.equal(data.culprit, '/app.js'); + assert.equal(data.culprit, 'app.js'); var frames = data.exception.values[0].stacktrace.frames; - assert.equal(frames[0].filename, '/file1.js'); - assert.equal(frames[1].filename, '/file2.js'); + assert.equal(frames[0].filename, 'file1.js'); + assert.equal(frames[1].filename, 'file2.js'); }); });