reactotron-react-native
Version:
A development tool to explore, inspect, and diagnose your React Native apps.
133 lines (124 loc) • 4.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _reactotronCoreClient = require("reactotron-core-client");
var _LogBox2 = _interopRequireDefault(require("react-native/Libraries/LogBox/LogBox"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Provides a global error handler to report errors..
*/
// eslint-disable-next-line import/namespace
const LogBox = _LogBox2.default;
// a few functions to help source map errors -- these seem to be not available immediately
// so we're lazy loading.
let parseErrorStack;
let symbolicateStackTrace;
// defaults
const PLUGIN_DEFAULTS = {
veto: null
};
const objectifyError = error => {
const objectifiedError = {};
Object.getOwnPropertyNames(error).forEach(key => {
objectifiedError[key] = error[key];
});
return objectifiedError;
};
// const reactNativeFrameFinder = frame => contains('/node_modules/react-native/', frame.fileName)
/**
* Track global errors and send them to Reactotron logger.
*/
const trackGlobalErrors = options => reactotron => {
// make sure we have the logger plugin
(0, _reactotronCoreClient.assertHasLoggerPlugin)(reactotron);
const client = reactotron;
// setup configuration
const config = Object.assign({}, PLUGIN_DEFAULTS, options || {});
// manually fire an error
function reportError(error) {
try {
if (!parseErrorStack) {
const parseErrorStackModule = require("react-native/Libraries/Core/Devtools/parseErrorStack");
// Handle both CommonJS (module.exports) and ESM (export default) formats
parseErrorStack = typeof parseErrorStackModule === "function" ? parseErrorStackModule : parseErrorStackModule.default;
}
if (!symbolicateStackTrace) {
const symbolicateStackTraceModule = require("react-native/Libraries/Core/Devtools/symbolicateStackTrace");
// Handle both CommonJS (module.exports) and ESM (export default) formats
symbolicateStackTrace = typeof symbolicateStackTraceModule === "function" ? symbolicateStackTraceModule : symbolicateStackTraceModule.default;
}
} catch (e) {
client.error('Unable to load "react-native/Libraries/Core/Devtools/parseErrorStack" or "react-native/Libraries/Core/Devtools/symbolicateStackTrace"', []);
client.debug(objectifyError(e));
return;
}
if (!parseErrorStack || !symbolicateStackTrace) {
client.error("parseErrorStack or symbolicateStackTrace is not available", []);
client.debug({
parseErrorStackAvailable: !!parseErrorStack,
symbolicateStackTraceAvailable: !!symbolicateStackTrace
});
return;
}
if (typeof parseErrorStack !== "function") {
client.error("parseErrorStack is not a function", []);
client.debug({
parseErrorStackType: typeof parseErrorStack,
parseErrorStack
});
return;
}
if (typeof symbolicateStackTrace !== "function") {
client.error("symbolicateStackTrace is not a function", []);
client.debug({
symbolicateStackTraceType: typeof symbolicateStackTrace,
symbolicateStackTrace
});
return;
}
let parsedStacktrace;
try {
// parseErrorStack arg type is wrong, it's expecting an array, a string, or a hermes error data, https://github.com/facebook/react-native/blob/v0.72.1/packages/react-native/Libraries/Core/Devtools/parseErrorStack.js#L41
parsedStacktrace = parseErrorStack(error.stack);
} catch (e) {
client.error("Unable to parse stack trace from error object", []);
client.debug(objectifyError(e));
return;
}
symbolicateStackTrace(parsedStacktrace).then(symbolicatedStackTrace => {
let prettyStackFrames = symbolicatedStackTrace.stack.map(stackFrame => ({
fileName: stackFrame.file,
functionName: stackFrame.methodName,
lineNumber: stackFrame.lineNumber
}));
// does the dev want us to keep each frame?
if (config.veto) {
prettyStackFrames = prettyStackFrames.filter(frame => config?.veto(frame));
}
client.error(error.message, prettyStackFrames); // TODO: Fix this.
}).catch(e => {
client.error("Unable to symbolicate stack trace from error object", []);
client.debug(objectifyError(e));
});
}
// the reactotron plugin interface
return {
onConnect: () => {
LogBox.addException = new Proxy(LogBox.addException, {
apply: function (target, thisArg, argumentsList) {
const error = argumentsList[0];
reportError(error);
return target.apply(thisArg, argumentsList);
}
});
},
// attach these functions to the Reactotron
features: {
reportError
}
};
};
var _default = exports.default = trackGlobalErrors;
//# sourceMappingURL=trackGlobalErrors.js.map