Report Java stack from errors from sync native module calls

Reviewed By: mhorowitz

Differential Revision: D5069794

fbshipit-source-id: ede314034a2eb6b063a22dbd6e5d13c8ad66e20c
This commit is contained in:
Pieter De Baets
2017-06-14 09:16:26 -07:00
committed by Facebook Github Bot
parent d67628eb5a
commit 534bbfac8f
10 changed files with 134 additions and 45 deletions

View File

@@ -15,6 +15,8 @@ const BatchedBridge = require('BatchedBridge');
const invariant = require('fbjs/lib/invariant');
import type {ExtendedError} from 'parseErrorStack';
type ModuleConfig = [
string, /* name */
?Object, /* constants */
@@ -113,13 +115,13 @@ function arrayContains<T>(array: Array<T>, value: T): boolean {
return array.indexOf(value) !== -1;
}
function createErrorFromErrorData(errorData: {message: string}): Error {
function createErrorFromErrorData(errorData: {message: string}): ExtendedError {
const {
message,
...extraErrorInfo
} = errorData;
const error = new Error(message);
(error:any).framesToPop = 1;
const error : ExtendedError = new Error(message);
error.framesToPop = 1;
return Object.assign(error, extraErrorInfo);
}

View File

@@ -18,20 +18,22 @@ export type StackFrame = {
methodName: string,
};
var stacktraceParser = require('stacktrace-parser');
export type ExtendedError = Error & {
framesToPop?: number,
};
function parseErrorStack(e: Error): Array<StackFrame> {
function parseErrorStack(e: ExtendedError): Array<StackFrame> {
if (!e || !e.stack) {
return [];
}
var stack = Array.isArray(e.stack) ? e.stack : stacktraceParser.parse(e.stack);
const stacktraceParser = require('stacktrace-parser');
const stack = Array.isArray(e.stack) ? e.stack : stacktraceParser.parse(e.stack);
var framesToPop = typeof e.framesToPop === 'number' ? e.framesToPop : 0;
let framesToPop = typeof e.framesToPop === 'number' ? e.framesToPop : 0;
while (framesToPop--) {
stack.shift();
}
return stack;
}

View File

@@ -11,11 +11,13 @@
*/
'use strict';
import type {ExtendedError} from 'parseErrorStack';
/**
* Handles the developer-visible aspect of errors and exceptions
*/
let exceptionID = 0;
function reportException(e: Error, isFatal: bool) {
function reportException(e: ExtendedError, isFatal: bool) {
const {ExceptionsManager} = require('NativeModules');
if (ExceptionsManager) {
const parseErrorStack = require('parseErrorStack');
@@ -84,7 +86,7 @@ function reactConsoleErrorHandler() {
// (Note: Logic duplicated in polyfills/console.js.)
return;
}
const error : any = new Error('console.error: ' + str);
const error : ExtendedError = new Error('console.error: ' + str);
error.framesToPop = 1;
reportException(error, /* isFatal */ false);
}

View File

@@ -16,10 +16,12 @@
const JSTimersExecution = require('JSTimersExecution');
const Platform = require('Platform');
const {Timing} = require('NativeModules');
const performanceNow = require('fbjs/lib/performanceNow');
const {Timing} = require('NativeModules');
import type {JSTimerType} from 'JSTimersExecution';
import type {ExtendedError} from 'parseErrorStack';
// Returns a free index if one is available, and the next consecutive index otherwise.
function _getFreeIndex(): number {
@@ -38,9 +40,9 @@ function _allocateCallback(func: Function, type: JSTimerType): number {
JSTimersExecution.types[freeIndex] = type;
if (__DEV__) {
const parseErrorStack = require('parseErrorStack');
const e = (new Error() : any);
e.framesToPop = 1;
const stack = parseErrorStack(e);
const error : ExtendedError = new Error();
error.framesToPop = 1;
const stack = parseErrorStack(error);
if (stack) {
JSTimersExecution.identifiers[freeIndex] = stack.shift();
}