mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-30 22:48:23 +08:00
Simplify logging exceptions from JS to native
Reviewed By: vjeux Differential Revision: D2615559 fb-gh-sync-id: ee931b3691251c8b6276699c6f927e47d8e8fd97
This commit is contained in:
committed by
facebook-github-bot-5
parent
d9b4c57e12
commit
0c83407dd2
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user