1*26ad19fcSEvan Bacon/** 2*26ad19fcSEvan Bacon * Copyright (c) 650 Industries. 3*26ad19fcSEvan Bacon * Copyright (c) Meta Platforms, Inc. and affiliates. 4*26ad19fcSEvan Bacon * 5*26ad19fcSEvan Bacon * This source code is licensed under the MIT license found in the 6*26ad19fcSEvan Bacon * LICENSE file in the root directory of this source tree. 7*26ad19fcSEvan Bacon */ 8*26ad19fcSEvan Bacon 9*26ad19fcSEvan Baconimport parseErrorStack from '../parseErrorStack'; 10*26ad19fcSEvan Bacon 11*26ad19fcSEvan Bacontype ExtendedError = any; 12*26ad19fcSEvan Bacon 13*26ad19fcSEvan Baconclass SyntheticError extends Error { 14*26ad19fcSEvan Bacon name: string = ''; 15*26ad19fcSEvan Bacon} 16*26ad19fcSEvan Bacon 17*26ad19fcSEvan Bacon/** 18*26ad19fcSEvan Bacon * Handles the developer-visible aspect of errors and exceptions 19*26ad19fcSEvan Bacon */ 20*26ad19fcSEvan Baconlet exceptionID = 0; 21*26ad19fcSEvan Bacon 22*26ad19fcSEvan Baconfunction parseException(e: ExtendedError, isFatal: boolean) { 23*26ad19fcSEvan Bacon const stack = parseErrorStack(e?.stack); 24*26ad19fcSEvan Bacon const currentExceptionID = ++exceptionID; 25*26ad19fcSEvan Bacon const originalMessage = e.message || ''; 26*26ad19fcSEvan Bacon let message = originalMessage; 27*26ad19fcSEvan Bacon if (e.componentStack != null) { 28*26ad19fcSEvan Bacon message += `\n\nThis error is located at:${e.componentStack}`; 29*26ad19fcSEvan Bacon } 30*26ad19fcSEvan Bacon const namePrefix = e.name == null || e.name === '' ? '' : `${e.name}: `; 31*26ad19fcSEvan Bacon 32*26ad19fcSEvan Bacon if (!message.startsWith(namePrefix)) { 33*26ad19fcSEvan Bacon message = namePrefix + message; 34*26ad19fcSEvan Bacon } 35*26ad19fcSEvan Bacon 36*26ad19fcSEvan Bacon message = e.jsEngine == null ? message : `${message}, js engine: ${e.jsEngine}`; 37*26ad19fcSEvan Bacon 38*26ad19fcSEvan Bacon const data = { 39*26ad19fcSEvan Bacon message, 40*26ad19fcSEvan Bacon originalMessage: message === originalMessage ? null : originalMessage, 41*26ad19fcSEvan Bacon name: e.name == null || e.name === '' ? null : e.name, 42*26ad19fcSEvan Bacon componentStack: typeof e.componentStack === 'string' ? e.componentStack : null, 43*26ad19fcSEvan Bacon stack, 44*26ad19fcSEvan Bacon id: currentExceptionID, 45*26ad19fcSEvan Bacon isFatal, 46*26ad19fcSEvan Bacon extraData: { 47*26ad19fcSEvan Bacon jsEngine: e.jsEngine, 48*26ad19fcSEvan Bacon rawStack: e.stack, 49*26ad19fcSEvan Bacon }, 50*26ad19fcSEvan Bacon }; 51*26ad19fcSEvan Bacon 52*26ad19fcSEvan Bacon return { 53*26ad19fcSEvan Bacon ...data, 54*26ad19fcSEvan Bacon isComponentError: !!e.isComponentError, 55*26ad19fcSEvan Bacon }; 56*26ad19fcSEvan Bacon} 57*26ad19fcSEvan Bacon 58*26ad19fcSEvan Bacon/** 59*26ad19fcSEvan Bacon * Logs exceptions to the (native) console and displays them 60*26ad19fcSEvan Bacon */ 61*26ad19fcSEvan Baconfunction handleException(e: any) { 62*26ad19fcSEvan Bacon let error: Error; 63*26ad19fcSEvan Bacon if (e instanceof Error) { 64*26ad19fcSEvan Bacon error = e; 65*26ad19fcSEvan Bacon } else { 66*26ad19fcSEvan Bacon // Workaround for reporting errors caused by `throw 'some string'` 67*26ad19fcSEvan Bacon // Unfortunately there is no way to figure out the stacktrace in this 68*26ad19fcSEvan Bacon // case, so if you ended up here trying to trace an error, look for 69*26ad19fcSEvan Bacon // `throw '<error message>'` somewhere in your codebase. 70*26ad19fcSEvan Bacon error = new SyntheticError(e); 71*26ad19fcSEvan Bacon } 72*26ad19fcSEvan Bacon 73*26ad19fcSEvan Bacon require('../../LogBox').default.addException(parseException(error, true)); 74*26ad19fcSEvan Bacon} 75*26ad19fcSEvan Bacon 76*26ad19fcSEvan Baconconst ErrorUtils = { 77*26ad19fcSEvan Bacon parseException, 78*26ad19fcSEvan Bacon handleException, 79*26ad19fcSEvan Bacon SyntheticError, 80*26ad19fcSEvan Bacon}; 81*26ad19fcSEvan Bacon 82*26ad19fcSEvan Baconexport default ErrorUtils; 83