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