Type ErrorUtils (error-guard.js)
Summary: * Adds Flow types to `error-guard.js` and propagates them via the `ErrorUtils` module. * Fixes some call sites to account for the stricter (correct) types. Differential Revision: D16619538 fbshipit-source-id: c006ff2736ec380763956c4b89702cf44dd4deb0
This commit is contained in:
Родитель
32c7e3a1aa
Коммит
9f85f1e39c
|
@ -11,9 +11,6 @@
|
|||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore polyfills
|
||||
.*/Libraries/polyfills/.*
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/warning')
|
||||
.*/node_modules/warning/.*
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore polyfills
|
||||
.*/Libraries/polyfills/.*
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/warning')
|
||||
.*/node_modules/warning/.*
|
||||
|
|
|
@ -99,16 +99,18 @@ declare var console: typeof console & {
|
|||
/**
|
||||
* Logs exceptions to the (native) console and displays them
|
||||
*/
|
||||
function handleException(e: Error, isFatal: boolean) {
|
||||
// Workaround for reporting errors caused by `throw 'some string'`
|
||||
// Unfortunately there is no way to figure out the stacktrace in this
|
||||
// case, so if you ended up here trying to trace an error, look for
|
||||
// `throw '<error message>'` somewhere in your codebase.
|
||||
if (!e.message) {
|
||||
// $FlowFixMe - cannot reassign constant, explanation above
|
||||
e = new SyntheticError(e);
|
||||
function handleException(e: mixed, isFatal: boolean) {
|
||||
let error: Error;
|
||||
if (e instanceof Error) {
|
||||
error = e;
|
||||
} else {
|
||||
// Workaround for reporting errors caused by `throw 'some string'`
|
||||
// Unfortunately there is no way to figure out the stacktrace in this
|
||||
// case, so if you ended up here trying to trace an error, look for
|
||||
// `throw '<error message>'` somewhere in your codebase.
|
||||
error = new SyntheticError(e);
|
||||
}
|
||||
reportException(e, isFatal);
|
||||
reportException(error, isFatal);
|
||||
}
|
||||
|
||||
function reactConsoleErrorHandler() {
|
||||
|
|
|
@ -5,18 +5,24 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
* @polyfill
|
||||
* @nolint
|
||||
*/
|
||||
|
||||
let _inGuard = 0;
|
||||
|
||||
type ErrorHandler = (error: mixed, isFatal: boolean) => void;
|
||||
type Fn<Args, Return> = (...Args) => Return;
|
||||
|
||||
/**
|
||||
* This is the error handler that is called when we encounter an exception
|
||||
* when loading a module. This will report any errors encountered before
|
||||
* ExceptionsManager is configured.
|
||||
*/
|
||||
let _globalHandler = function onError(e) {
|
||||
let _globalHandler: ErrorHandler = function onError(
|
||||
e: mixed,
|
||||
isFatal: boolean,
|
||||
) {
|
||||
throw e;
|
||||
};
|
||||
|
||||
|
@ -29,21 +35,31 @@ let _globalHandler = function onError(e) {
|
|||
* set) globally before requiring anything.
|
||||
*/
|
||||
const ErrorUtils = {
|
||||
setGlobalHandler(fun) {
|
||||
setGlobalHandler(fun: ErrorHandler): void {
|
||||
_globalHandler = fun;
|
||||
},
|
||||
getGlobalHandler() {
|
||||
getGlobalHandler(): ErrorHandler {
|
||||
return _globalHandler;
|
||||
},
|
||||
reportError(error) {
|
||||
_globalHandler && _globalHandler(error);
|
||||
reportError(error: mixed): void {
|
||||
_globalHandler && _globalHandler(error, false);
|
||||
},
|
||||
reportFatalError(error) {
|
||||
reportFatalError(error: mixed): void {
|
||||
// NOTE: This has an untyped call site in Metro.
|
||||
_globalHandler && _globalHandler(error, true);
|
||||
},
|
||||
applyWithGuard(fun, context, args) {
|
||||
applyWithGuard<TArgs: $ReadOnlyArray<mixed>, TOut>(
|
||||
fun: Fn<TArgs, TOut>,
|
||||
context?: ?mixed,
|
||||
args?: ?TArgs,
|
||||
// Unused, but some code synced from www sets it to null.
|
||||
unused_onError?: null,
|
||||
// Some callers pass a name here, which we ignore.
|
||||
unused_name?: ?string,
|
||||
): ?TOut {
|
||||
try {
|
||||
_inGuard++;
|
||||
// $FlowFixMe: TODO T48204745 (1) apply(context, null) is fine. (2) array -> rest array should work
|
||||
return fun.apply(context, args);
|
||||
} catch (e) {
|
||||
ErrorUtils.reportError(e);
|
||||
|
@ -52,30 +68,41 @@ const ErrorUtils = {
|
|||
}
|
||||
return null;
|
||||
},
|
||||
applyWithGuardIfNeeded(fun, context, args) {
|
||||
applyWithGuardIfNeeded<TArgs: $ReadOnlyArray<mixed>, TOut>(
|
||||
fun: Fn<TArgs, TOut>,
|
||||
context?: ?mixed,
|
||||
args?: ?TArgs,
|
||||
): ?TOut {
|
||||
if (ErrorUtils.inGuard()) {
|
||||
// $FlowFixMe: TODO T48204745 (1) apply(context, null) is fine. (2) array -> rest array should work
|
||||
return fun.apply(context, args);
|
||||
} else {
|
||||
ErrorUtils.applyWithGuard(fun, context, args);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
inGuard() {
|
||||
return _inGuard;
|
||||
inGuard(): boolean {
|
||||
return !!_inGuard;
|
||||
},
|
||||
guard(fun, name, context) {
|
||||
guard<TArgs: $ReadOnlyArray<mixed>, TOut>(
|
||||
fun: Fn<TArgs, TOut>,
|
||||
name?: ?string,
|
||||
context?: ?mixed,
|
||||
): ?(...TArgs) => ?TOut {
|
||||
// TODO: (moti) T48204753 Make sure this warning is never hit and remove it - types
|
||||
// should be sufficient.
|
||||
if (typeof fun !== 'function') {
|
||||
console.warn('A function must be passed to ErrorUtils.guard, got ', fun);
|
||||
return null;
|
||||
}
|
||||
name = name || fun.name || '<generated guard>';
|
||||
function guarded() {
|
||||
const guardName = name ?? fun.name ?? '<generated guard>';
|
||||
function guarded(...args: TArgs): ?TOut {
|
||||
return ErrorUtils.applyWithGuard(
|
||||
fun,
|
||||
context || this,
|
||||
arguments,
|
||||
context ?? this,
|
||||
args,
|
||||
null,
|
||||
name,
|
||||
guardName,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -84,3 +111,5 @@ const ErrorUtils = {
|
|||
};
|
||||
|
||||
global.ErrorUtils = ErrorUtils;
|
||||
|
||||
export type ErrorUtilsT = typeof ErrorUtils;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* @flow strict
|
||||
*/
|
||||
|
||||
/* eslint-disable strict */
|
||||
import type {ErrorUtilsT} from '../../polyfills/error-guard.js';
|
||||
|
||||
/**
|
||||
* The particular require runtime that we are using looks for a global
|
||||
|
@ -22,4 +22,4 @@
|
|||
* that use it aren't just using a global variable, so simply export the global
|
||||
* variable here. ErrorUtils is originally defined in a file named error-guard.js.
|
||||
*/
|
||||
module.exports = global.ErrorUtils;
|
||||
module.exports = (global.ErrorUtils: ErrorUtilsT);
|
||||
|
|
Загрузка…
Ссылка в новой задаче