diff --git a/Libraries/JavaScriptAppEngine/Initialization/ExceptionsManager.js b/Libraries/JavaScriptAppEngine/Initialization/ExceptionsManager.js index 42c8e9d1d..e5eae65b4 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/ExceptionsManager.js +++ b/Libraries/JavaScriptAppEngine/Initialization/ExceptionsManager.js @@ -18,6 +18,7 @@ let exceptionID = 0; */ function reportException(e: Error, isFatal: bool) { const parseErrorStack = require('parseErrorStack'); + const symbolicateStackTrace = require('symbolicateStackTrace'); const RCTExceptionsManager = require('NativeModules').ExceptionsManager; const currentExceptionID = ++exceptionID; @@ -29,31 +30,16 @@ function reportException(e: Error, isFatal: bool) { RCTExceptionsManager.reportSoftException(e.message, stack, currentExceptionID); } if (__DEV__) { - symbolicateAndUpdateStack(currentExceptionID, e.message, stack); + symbolicateStackTrace(stack).then( + (prettyStack) => + RCTExceptionsManager.updateExceptionMessage(e.message, prettyStack, currentExceptionID), + (error) => + console.warn('Unable to symbolicate stack trace: ' + error.message) + ); } } } -function symbolicateAndUpdateStack(id, message, stack) { - const getDevServer = require('getDevServer'); - const {fetch} = require('fetch'); - const {ExceptionsManager} = require('NativeModules'); - const devServer = getDevServer(); - if (!devServer.bundleLoadedFromServer) { - return; - } - - fetch(devServer.url + 'symbolicate', { method: 'POST', body: JSON.stringify({stack}) }) - .then(response => response.json()) - .then(response => - ExceptionsManager.updateExceptionMessage(message, response.stack, id)) - .catch(error => { - // This can happen in a variety of normal situations, such as - // Network module not being available, or when running locally - console.warn('Unable to symbolicate stack trace: ' + error.message); - }); -} - /** * Logs exceptions to the (native) console and displays them */ diff --git a/Libraries/JavaScriptAppEngine/Initialization/parseErrorStack.js b/Libraries/JavaScriptAppEngine/Initialization/parseErrorStack.js index 5fec94315..1b0d66331 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/parseErrorStack.js +++ b/Libraries/JavaScriptAppEngine/Initialization/parseErrorStack.js @@ -7,31 +7,19 @@ * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule parseErrorStack + * @flow */ 'use strict'; +export type StackFrame = { + file: string; + lineNumber: number; + column: number; +}; + var stacktraceParser = require('stacktrace-parser'); -function resolveSourceMaps(sourceMapInstance, stackFrame) { - try { - var orig = sourceMapInstance.originalPositionFor({ - line: stackFrame.lineNumber, - column: stackFrame.column, - }); - if (orig) { - // remove query string if any - const queryStringStartIndex = orig.source.indexOf('?'); - stackFrame.file = queryStringStartIndex === -1 - ? orig.source - : orig.source.substring(0, queryStringStartIndex); - stackFrame.lineNumber = orig.line; - stackFrame.column = orig.column; - } - } catch (innerEx) { - } -} - -function parseErrorStack(e, sourceMaps) { +function parseErrorStack(e: Error): Array { if (!e || !e.stack) { return []; } @@ -43,19 +31,6 @@ function parseErrorStack(e, sourceMaps) { stack.shift(); } - if (sourceMaps) { - sourceMaps.forEach((sourceMap, index) => { - stack.forEach(frame => { - if (frame.file.indexOf(sourceMap.file) !== -1 || - frame.file.replace('.map', '.bundle').indexOf( - sourceMap.file - ) !== -1) { - resolveSourceMaps(sourceMap, frame); - } - }); - }); - } - return stack; } diff --git a/Libraries/JavaScriptAppEngine/Initialization/symbolicateStackTrace.js b/Libraries/JavaScriptAppEngine/Initialization/symbolicateStackTrace.js new file mode 100644 index 000000000..122837dad --- /dev/null +++ b/Libraries/JavaScriptAppEngine/Initialization/symbolicateStackTrace.js @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule symbolicateStackTrace + * @flow + */ +'use strict'; + +const {fetch} = require('fetch'); +const getDevServer = require('getDevServer'); + +import type {StackFrame} from 'parseErrorStack'; + +async function symbolicateStackTrace(stack: Array): Promise> { + const devServer = getDevServer(); + if (!devServer.bundleLoadedFromServer) { + throw new Error('Bundle was not loaded from the packager'); + } + const response = await fetch(devServer.url + 'symbolicate', { + method: 'POST', + body: JSON.stringify({stack}), + }); + const json = await response.json(); + return json.stack; +} + +module.exports = symbolicateStackTrace;