local U=require("\046\047\105\110\118\097\114\105\097\110\116")local S=require("\046\047\105\110\118\111\107\101\071\117\097\114\100\101\100\067\097\108\108\098\097\099\107\073\109\112\108")local Z local q=false local i=nil local r=false local x=nil local N={onError=function(U)q=true i=U end}local w={}w.invokeGuardedCallback=function(...)q=false i=nil S(N,...)end w.invokeGuardedCallbackAndCatchFirstError=function(...)w.invokeGuardedCallback(...)if q then local U=Z()if not r then r=true x=U end end end w.rethrowCaughtError=function()if r then local U=x r=false x=nil error(U)end end w.hasCaughtError=function()return q end Z=function()if q then local U=i q=false i=nil return U else U(false,"\099\108\101\097\114\067\097\117\103\104\116\069\114\114\111\114 \119\097\115 \099\097\108\108\101\100 \098\117\116 \110\111 \101\114\114\111\114 \119\097\115 \099\097\112\116\117\114\101\100\046 \084\104\105\115 \101\114\114\111\114 \105\115 \108\105\107\101\108\121 \099\097\117\115\101\100 \098\121 \097 \098\117\103 \105\110 \082\101\097\099\116\046 \080\108\101\097\115\101 \102\105\108\101 \097\110 \105\115\115\117\101\046")return nil end end w.clearCaughtError=Z return w
--!strict
-- ROBLOX upstream: https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/shared/ReactErrorUtils.js
--[[*
 * 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
]]
local invariant = require("./invariant")
local invokeGuardedCallbackImpl = require("./invokeGuardedCallbackImpl")

-- deviation: preemptively declare function
local clearCaughtError

-- Used by Fiber to simulate a try-catch.
local hasError = false
local caughtError = nil

-- Used by event system to capture/rethrow the first error.
local hasRethrowError = false
local rethrowError = nil
local reporter = {
	onError = function(err)
		hasError = true
		caughtError = err
	end,
}
local exports = {}

--[[*
* Call a function while guarding against errors that happens within it.
* Returns an error if it throws, otherwise nil.
*
* 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
]]
exports.invokeGuardedCallback = function(...)
	hasError = false
	caughtError = nil
	-- deviation: passing in reporter directly
	invokeGuardedCallbackImpl(reporter, ...)
end

--[[*
* 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
]]
exports.invokeGuardedCallbackAndCatchFirstError = function(...)
	-- deviation: instead of the weird `this` indirection, pass varargs through
	exports.invokeGuardedCallback(...)

	if hasError then
		local err = clearCaughtError()

		if not hasRethrowError then
			hasRethrowError = true
			rethrowError = err
		end
	end
end

--[[*
* During execution of guarded functions we will capture the first error which
* we will rethrow to be handled by the top level error handler.
]]
exports.rethrowCaughtError = function()
	if hasRethrowError then
		local err = rethrowError
		hasRethrowError = false
		rethrowError = nil
		error(err)
	end
end

exports.hasCaughtError = function()
	return hasError
end

clearCaughtError = function()
	if hasError then
		local err = caughtError
		hasError = false
		caughtError = nil
		return err
	else
		invariant(
			false,
			"clearCaughtError was called but no error was captured. This error "
				.. "is likely caused by a bug in React. Please file an issue."
		)
		-- deviation: luau doesn't know that invariant throws, so we return nil
		return nil
	end
end
exports.clearCaughtError = clearCaughtError

return exports
