Simplify logging exceptions from JS to native

Reviewed By: vjeux

Differential Revision: D2615559

fb-gh-sync-id: ee931b3691251c8b6276699c6f927e47d8e8fd97
This commit is contained in:
Pieter De Baets
2015-11-05 12:20:15 -08:00
committed by facebook-github-bot-5
parent d9b4c57e12
commit 0c83407dd2
3 changed files with 65 additions and 104 deletions

View File

@@ -21,12 +21,13 @@ var sourceMapPromise;
var exceptionID = 0;
function reportException(e: Error, isFatal: bool, stack?: any) {
/**
* Handles the developer-visible aspect of errors and exceptions
*/
function reportException(e: Error, isFatal: bool) {
var currentExceptionID = ++exceptionID;
if (RCTExceptionsManager) {
if (!stack) {
stack = parseErrorStack(e);
}
var stack = parseErrorStack(e);
if (isFatal) {
RCTExceptionsManager.reportFatalException(e.message, stack, currentExceptionID);
} else {
@@ -47,6 +48,9 @@ function reportException(e: Error, isFatal: bool, stack?: any) {
}
}
/**
* Logs exceptions to the (native) console and displays them
*/
function handleException(e: Error, isFatal: boolean) {
// Workaround for reporting errors caused by `throw 'some string'`
// Unfortunately there is no way to figure out the stacktrace in this
@@ -55,19 +59,9 @@ function handleException(e: Error, isFatal: boolean) {
if (!e.message) {
e = new Error(e);
}
var stack = parseErrorStack(e);
var msg =
'Error: ' + e.message +
'\n stack: \n' + stackToString(stack) +
'\n URL: ' + (e: any).sourceURL +
'\n line: ' + (e: any).line +
'\n message: ' + e.message;
if (console.errorOriginal) {
console.errorOriginal(msg);
} else {
console.error(msg);
}
reportException(e, isFatal, stack);
(console._errorOriginal || console.error)(e.message);
reportException(e, isFatal);
}
/**
@@ -75,54 +69,35 @@ function handleException(e: Error, isFatal: boolean) {
* setting `console.reportErrorsAsExceptions = false;` in your app.
*/
function installConsoleErrorReporter() {
if (console.reportException) {
// Enable reportErrorsAsExceptions
if (console._errorOriginal) {
return; // already installed
}
console.reportException = reportException;
console.errorOriginal = console.error.bind(console);
console._errorOriginal = console.error.bind(console);
console.error = function reactConsoleError() {
// Note that when using the built-in context executor on iOS (i.e., not
// Chrome debugging), console.error is already stubbed out to cause a
// redbox via RCTNativeLoggingHook.
console.errorOriginal.apply(null, arguments);
console._errorOriginal.apply(null, arguments);
if (!console.reportErrorsAsExceptions) {
return;
}
var str = Array.prototype.map.call(arguments, stringifySafe).join(', ');
if (str.slice(0, 10) === '"Warning: ') {
// React warnings use console.error so that a stack trace is shown, but
// we don't (currently) want these to show a redbox
// (Note: Logic duplicated in polyfills/console.js.)
return;
if (arguments[0] && arguments[0].stack) {
reportException(arguments[0], /* isFatal */ false);
} else {
var str = Array.prototype.map.call(arguments, stringifySafe).join(', ');
if (str.slice(0, 10) === '"Warning: ') {
// React warnings use console.error so that a stack trace is shown, but
// we don't (currently) want these to show a redbox
// (Note: Logic duplicated in polyfills/console.js.)
return;
}
var error : any = new Error('console.error: ' + str);
error.framesToPop = 1;
reportException(error, /* isFatal */ false);
}
var error: any = new Error('console.error: ' + str);
error.framesToPop = 1;
reportException(error, /* isFatal */ false);
};
if (console.reportErrorsAsExceptions === undefined) {
console.reportErrorsAsExceptions = true; // Individual apps can disable this
}
}
function stackToString(stack) {
var maxLength = Math.max.apply(null, stack.map(frame => frame.methodName.length));
return stack.map(frame => stackFrameToString(frame, maxLength)).join('\n');
}
function stackFrameToString(stackFrame, maxLength) {
var fileNameParts = stackFrame.file.split('/');
var fileName = fileNameParts[fileNameParts.length - 1];
if (fileName.length > 18) {
fileName = fileName.substr(0, 17) + '\u2026'; /* ... */
}
var spaces = fillSpaces(maxLength - stackFrame.methodName.length);
return ' ' + stackFrame.methodName + spaces + ' ' + fileName + ':' + stackFrame.lineNumber;
}
function fillSpaces(n) {
return new Array(n + 1).join(' ');
}
module.exports = { handleException, installConsoleErrorReporter };