UNPKG

react-native-site24x7-rn

Version:

Monitor react native mobile applications with site24x7 Mobile RUM

124 lines (116 loc) 5.33 kB
import S24Utils from './site24x7Utils'; const { NativeModules } = require('react-native');//No I18N const MAX_STACK_TRACE_LEN = 20; const EMPTY_STACK_TRACE=""; const ANONYMOUS="?"; const { Site24x7Rn } = NativeModules; class site24x7RnErrorTracker{ constructor(enableErrorTracking,enableConsoleErrors,enableUnhandledRejections){ this.enableErrorTracking = enableErrorTracking; this.enableConsoleErrors = enableConsoleErrors; this.enableUnhandledRejections = enableUnhandledRejections; if(this.enableErrorTracking){ //making a copy of previous old error handler. const oldJsExceptionHandler = ErrorUtils.getGlobalHandler(); //intercepting global error handler before returning to the original error handler. ErrorUtils.setGlobalHandler(async (error, isFatal) => { await this.parseError(error, isFatal); oldJsExceptionHandler && oldJsExceptionHandler(error, isFatal); }); } //need to get file exclusion for code check from integ team // if(this.enableConsoleErrors){ // const consoleError = console.error; // console.error = (...args) => { // ErrorUtils.reportError(...args); // consoleError(...args); // }; // } // https://github.com/iyegoroff/react-native-promise-rejection-utils/blob/master/index.js if(this.enableUnhandledRejections){ const { polyfillGlobal } = require('react-native/Libraries/Utilities/PolyfillFunctions');//No I18N const Promise = require('promise/setimmediate/es6-extensions');//No I18N const tracking = require('promise/setimmediate/rejection-tracking');//No I18N // Set up rejection handler to divert rejections to crash reporter polyfillGlobal('Promise', () => {//No I18N tracking.enable({ allRejections: true, onUnhandled: site24x7RnErrorTracker.parseUnhandledRejection.bind(this) }); return Promise; }); } } //Not used Currently static getErrorStackTrace(error) { let stack = EMPTY_STACK_TRACE; if ('componentStack' in error) { stack = String(error.componentStack); } else if ('sourceURL' in error && 'line' in error && 'column' in error) { stack = `at ${error.sourceURL}:${error.line}:${error.column}`; } return stack; } static parseUnhandledRejection(id, error) { if (__DEV__) { const warning =`site24x7mobileRUM Possible Unhandled Promise Rejection (id: ${id}):\n` +`${error}\n`; //console.warn(warning) } this.parseError(error, false); } async parseError(error, isFatal) { this.parseErrorWithHandledExceptionCheck(error, isFatal, false); } async parseErrorWithHandledExceptionCheck(error, isFatal, handledException) { if (S24Utils.isEmpty(error) || S24Utils.isEmpty(error.stack)) { return; } const parseErrorStack = require('react-native/Libraries/Core/Devtools/parseErrorStack');//No I18N let stack; try { stack = parseErrorStack(error); } catch (e) {// parseErrorStack in ReactNative 0.64 requires a string stack = parseErrorStack(error.stack); } const errorData = await this.site24x7RumError(stack,error); Site24x7Rn.addJsError(errorData.msg,errorData.type,errorData.file,errorData.function,errorData.stack,JSON.stringify(errorData.breadcrumbs),S24Utils.getCurrentScreen(),Date.now().toString(), handledException); S24Utils.clearBreadCrumbs();//No I18N } async site24x7RumError(stack,error){ stack = S24Utils.cleanFilePath(stack); error = S24Utils.isEmpty(error) ? {"name":ANONYMOUS,"message":ANONYMOUS} : error;//No I18N const errorDetails = { "breadcrumbs" : S24Utils.getBreadCrumbs(),//No I18N "type" : error.name,//No I18N "msg" : error.message,//No I18N "stack" : await this.computeStackTrace(stack)//No I18N }; if(stack.length>0){ errorDetails.function = stack[0].methodName || ANONYMOUS; errorDetails.file = stack[0].file; }else{ errorDetails.function = ANONYMOUS; errorDetails.file = ANONYMOUS; } return errorDetails; } async computeStackTrace(stack){ const convertToCrashReportingStackFrame = ({ file, methodName, lineNumber, column }) => ({ fname: file, func: methodName || ANONYMOUS, lineno: lineNumber, colno: column }); stack = Array.isArray(stack) ? stack.map(convertToCrashReportingStackFrame) : [convertToCrashReportingStackFrame(stack)]; if(Array.isArray(stack)){ //removing native code errors from stack trace stack = stack.filter((item)=>{ return item.fname.indexOf("native code") == -1; }) stack=stack.slice(Math.max(stack.length - MAX_STACK_TRACE_LEN, 0)); } return JSON.stringify(stack); } } module.exports = site24x7RnErrorTracker;