/*** Copyright (c) Meta Platforms, Inc. and affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.** @flow*/import invokeGuardedCallbackImpl from './invokeGuardedCallbackImpl';
// Used by Fiber to simulate a try-catch.let hasError: boolean = false;
let caughtError: mixed = null;
// Used by event system to capture/rethrow the first error.let hasRethrowError: boolean = false;
let rethrowError: mixed = null;
const reporter = {
onError(error: mixed) {
hasError = true;
caughtError = error;
},};/*** Call a function while guarding against errors that happens within it.* Returns an error if it throws, otherwise null.** In production, this is implemented using a try-catch. The reason we don't* use a try-catch directly is so that we can swap out a different* implementation in DEV mode.** @param {String} name of the guard to use for logging or debugging* @param {Function} func The function to invoke* @param {*} context The context to use when calling the function* @param {...*} args Arguments for function*/export function invokeGuardedCallback<A, B, C, D, E, F, Context>(
name: string | null,
func: (a: A, b: B, c: C, d: D, e: E, f: F) => mixed,
context: Context,
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
): void {
hasError = false;caughtError = null;invokeGuardedCallbackImpl.apply(reporter, arguments);
}/*** Same as invokeGuardedCallback, but instead of returning an error, it stores* it in a global so it can be rethrown by `rethrowCaughtError` later.* TODO: See if caughtError and rethrowError can be unified.** @param {String} name of the guard to use for logging or debugging* @param {Function} func The function to invoke* @param {*} context The context to use when calling the function* @param {...*} args Arguments for function*/export function invokeGuardedCallbackAndCatchFirstError<
A,
B,
C,
D,
E,
F,
Context,
>(this: mixed,
name: string | null,
func: (a: A, b: B, c: C, d: D, e: E, f: F) => void,
context: Context,
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
): void {
invokeGuardedCallback.apply(this, arguments);
if (hasError) {
const error = clearCaughtError();
if (!hasRethrowError) {
hasRethrowError = true;
rethrowError = error;
}}}/*** During execution of guarded functions we will capture the first error which* we will rethrow to be handled by the top level error handler.*/export function rethrowCaughtError() {
if (hasRethrowError) {
const error = rethrowError;
hasRethrowError = false;
rethrowError = null;
throw error;
}}export function hasCaughtError(): boolean {
return hasError;}export function clearCaughtError(): mixed {
if (hasError) {
const error = caughtError;
hasError = false;
caughtError = null;
return error;
} else {throw new Error(
'clearCaughtError was called but no error was captured. This error ' +'is likely caused by a bug in React. Please file an issue.',);}}