function Rx.catchError(f)assert(type(f)=="\102\117\110\099\116\105\111\110","\066\097\100 \099\097\108\108\098\097\099\107")return function(S)assert(Observable.isObservable(S),"\066\097\100 \111\098\115\101\114\118\097\098\108\101")return Observable.new(function(m)local x=Maid.new()local s=true x:GiveTask(function()s=false end)x:GiveTask(S:Subscribe(function(...)m:Fire(...)end,function(...)if not s then return end local S=f(...)assert(Observable.isObservable(S),"\066\097\100 \111\098\115\101\114\118\097\098\108\101")x:GiveTask(S:Subscribe(m:GetFireFailComplete()))end,function()m:Complete()end))return x end)end end
--[=[
	Catches an error, and allows another observable to be subscribed
	in terms of handling the error.

	:::warning
	This method is not yet tested
	:::

	@param callback (error: TError) -> Observable<TErrorResult>
	@return (source: Observable<T>) -> Observable<T | TErrorResult>
]=]
function Rx.catchError(callback)
	assert(type(callback) == "function", "Bad callback")

	return function(source)
		assert(Observable.isObservable(source), "Bad observable")

		return Observable.new(function(sub)
			local maid = Maid.new()

			-- Yikes, let's hope event ordering is good
			local alive = true
			maid:GiveTask(function()
				alive = false
			end)

			maid:GiveTask(source:Subscribe(function(...)
				sub:Fire(...)
			end, function(...)
				if not alive then
					-- if we failed because maid was cancelled, then we'll get called here?
					-- I think.
					return
				end

				-- at this point, we can only have one error, so we need to subscribe to the result
				-- and continue the observiable
				local observable = callback(...)
				assert(Observable.isObservable(observable), "Bad observable")

				maid:GiveTask(observable:Subscribe(sub:GetFireFailComplete()))
			end, function()
				sub:Complete()
			end))

			return maid
		end)
	end
end
