From e82b489579ac0c23526ccf922a317b38757ecc1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 22 May 2019 13:04:35 -0700 Subject: [PATCH] Add spec for ExceptionsManager (#24900) Summary: Part of #24875, adds a spec for ExceptionsManager ## Changelog [General] [Added] - TM Add spec for ExceptionsManager Pull Request resolved: https://github.com/facebook/react-native/pull/24900 Reviewed By: fkgozali Differential Revision: D15434006 Pulled By: RSNara fbshipit-source-id: 1a505744a84c0c4ac3a9fac6c91a391fbd8a9f46 --- Libraries/Core/Devtools/parseErrorStack.js | 7 +-- .../Core/Devtools/symbolicateStackTrace.js | 2 +- Libraries/Core/ExceptionsManager.js | 19 +++++--- Libraries/Core/NativeExceptionsManager.js | 43 +++++++++++++++++++ Libraries/Utilities/HMRClient.js | 10 ++--- .../YellowBox/Data/YellowBoxSymbolication.js | 2 +- .../__tests__/YellowBoxSymbolication-test.js | 2 +- .../Data/__tests__/YellowBoxWarning-test.js | 2 +- .../UI/YellowBoxInspectorStackFrame.js | 2 +- 9 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 Libraries/Core/NativeExceptionsManager.js diff --git a/Libraries/Core/Devtools/parseErrorStack.js b/Libraries/Core/Devtools/parseErrorStack.js index a826630355df32..441800dac8cf90 100644 --- a/Libraries/Core/Devtools/parseErrorStack.js +++ b/Libraries/Core/Devtools/parseErrorStack.js @@ -10,12 +10,7 @@ 'use strict'; -export type StackFrame = { - column: ?number, - file: string, - lineNumber: number, - methodName: string, -}; +import type {StackFrame} from '../NativeExceptionsManager'; export type ExtendedError = Error & { framesToPop?: number, diff --git a/Libraries/Core/Devtools/symbolicateStackTrace.js b/Libraries/Core/Devtools/symbolicateStackTrace.js index 32e209ef78f59c..1c6552a1591d7a 100644 --- a/Libraries/Core/Devtools/symbolicateStackTrace.js +++ b/Libraries/Core/Devtools/symbolicateStackTrace.js @@ -17,7 +17,7 @@ import NativeSourceCode from '../../NativeModules/specs/NativeSourceCode'; // Avoid requiring fetch on load of this module; see symbolicateStackTrace let fetch; -import type {StackFrame} from './parseErrorStack'; +import type {StackFrame} from '../NativeExceptionsManager'; function isSourcedFromDisk(sourcePath: string): boolean { return !/^http/.test(sourcePath) && /[\\/]/.test(sourcePath); diff --git a/Libraries/Core/ExceptionsManager.js b/Libraries/Core/ExceptionsManager.js index 24ca07b5891b9a..9ccd725d4294ca 100644 --- a/Libraries/Core/ExceptionsManager.js +++ b/Libraries/Core/ExceptionsManager.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @flow + * @flow strict-local */ 'use strict'; @@ -24,21 +24,25 @@ const INTERNAL_CALLSITES_REGEX = new RegExp( */ let exceptionID = 0; function reportException(e: ExtendedError, isFatal: boolean) { - const {ExceptionsManager} = require('../BatchedBridge/NativeModules'); - if (ExceptionsManager) { + const NativeExceptionsManager = require('./NativeExceptionsManager').default; + if (NativeExceptionsManager) { const parseErrorStack = require('./Devtools/parseErrorStack'); const stack = parseErrorStack(e); const currentExceptionID = ++exceptionID; const message = e.jsEngine == null ? e.message : `${e.message}, js engine: ${e.jsEngine}`; if (isFatal) { - ExceptionsManager.reportFatalException( + NativeExceptionsManager.reportFatalException( message, stack, currentExceptionID, ); } else { - ExceptionsManager.reportSoftException(message, stack, currentExceptionID); + NativeExceptionsManager.reportSoftException( + message, + stack, + currentExceptionID, + ); } if (__DEV__) { const symbolicateStackTrace = require('./Devtools/symbolicateStackTrace'); @@ -50,7 +54,7 @@ function reportException(e: ExtendedError, isFatal: boolean) { frame.file && frame.file.match(INTERNAL_CALLSITES_REGEX) === null, ); - ExceptionsManager.updateExceptionMessage( + NativeExceptionsManager.updateExceptionMessage( message, stackWithoutInternalCallsites, currentExceptionID, @@ -67,7 +71,7 @@ function reportException(e: ExtendedError, isFatal: boolean) { } declare var console: typeof console & { - _errorOriginal: Function, + _errorOriginal: typeof console.error, reportErrorsAsExceptions: boolean, }; @@ -80,6 +84,7 @@ function handleException(e: Error, isFatal: boolean) { // case, so if you ended up here trying to trace an error, look for // `throw ''` somewhere in your codebase. if (!e.message) { + // $FlowFixMe - cannot reassign constant, explanation above e = new Error(e); } if (console._errorOriginal) { diff --git a/Libraries/Core/NativeExceptionsManager.js b/Libraries/Core/NativeExceptionsManager.js new file mode 100644 index 00000000000000..f9a82ec6389e06 --- /dev/null +++ b/Libraries/Core/NativeExceptionsManager.js @@ -0,0 +1,43 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {TurboModule} from 'RCTExport'; +import * as TurboModuleRegistry from 'TurboModuleRegistry'; + +export type StackFrame = {| + column: ?number, + file: string, + lineNumber: number, + methodName: string, +|}; + +export interface Spec extends TurboModule { + +reportFatalException: ( + message: string, + stack: Array, + exceptionId: number, + ) => void; + +reportSoftException: ( + message: string, + stack: Array, + exceptionId: number, + ) => void; + +updateExceptionMessage: ( + message: string, + stack: Array, + exceptionId: number, + ) => void; + // Android only + +dismissRedbox: () => void; +} + +export default TurboModuleRegistry.getEnforcing('ExceptionsManager'); diff --git a/Libraries/Utilities/HMRClient.js b/Libraries/Utilities/HMRClient.js index bb5b3ab69bcdd7..eb34d2d83ecc8d 100644 --- a/Libraries/Utilities/HMRClient.js +++ b/Libraries/Utilities/HMRClient.js @@ -81,11 +81,11 @@ Error: ${e.message}`; ) { NativeRedBox.dismiss(); } else { - const RCTExceptionsManager = require('../BatchedBridge/NativeModules') - .ExceptionsManager; - RCTExceptionsManager && - RCTExceptionsManager.dismissRedbox && - RCTExceptionsManager.dismissRedbox(); + const NativeExceptionsManager = require('../Core/NativeExceptionsManager') + .default; + NativeExceptionsManager && + NativeExceptionsManager.dismissRedbox && + NativeExceptionsManager.dismissRedbox(); } }); diff --git a/Libraries/YellowBox/Data/YellowBoxSymbolication.js b/Libraries/YellowBox/Data/YellowBoxSymbolication.js index f8186daeeb9868..d31d6ef06b757c 100644 --- a/Libraries/YellowBox/Data/YellowBoxSymbolication.js +++ b/Libraries/YellowBox/Data/YellowBoxSymbolication.js @@ -12,7 +12,7 @@ const symbolicateStackTrace = require('../../Core/Devtools/symbolicateStackTrace'); -import type {StackFrame} from '../../Core/Devtools/parseErrorStack'; +import type {StackFrame} from '../../Core/NativeExceptionsManager'; type CacheKey = string; diff --git a/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js b/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js index b438ab1142e92d..f125ff380f040a 100644 --- a/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js +++ b/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js @@ -11,7 +11,7 @@ 'use strict'; -import type {StackFrame} from '../../../Core/Devtools/parseErrorStack'; +import type {StackFrame} from '../../../Core/NativeExceptionsManager'; jest.mock('../../../Core/Devtools/symbolicateStackTrace'); diff --git a/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js b/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js index 65369bf8e5e60f..3bbca34dd569e7 100644 --- a/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js +++ b/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js @@ -11,7 +11,7 @@ 'use strict'; -import type {StackFrame} from '../../../Core/Devtools/parseErrorStack'; +import type {StackFrame} from '../../../Core/NativeExceptionsManager'; jest.mock('../YellowBoxSymbolication'); diff --git a/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js b/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js index efac349d35ee3c..47985c8b117e20 100644 --- a/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js +++ b/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js @@ -17,7 +17,7 @@ const YellowBoxPressable = require('./YellowBoxPressable'); const YellowBoxStyle = require('./YellowBoxStyle'); import type {PressEvent} from '../../Types/CoreEventTypes'; -import type {StackFrame} from '../../Core/Devtools/parseErrorStack'; +import type {StackFrame} from '../../Core/NativeExceptionsManager'; type Props = $ReadOnly<{| frame: StackFrame,