function Rx.catchError(c)assert(type(c)=="\102\117\110\099\116\105\111\110","\066\097\100 \099\097\108\108\098\097\099\107")return function(r)assert(Observable.isObservable(r),"\066\097\100 \111\098\115\101\114\118\097\098\108\101")return Observable.new(function(p)local n=Maid.new()local x=true n:GiveTask(function()x=false end)n:GiveTask(r:Subscribe(function(...)p:Fire(...)end,function(...)if not x then return end local r=c(...)assert(Observable.isObservable(r),"\066\097\100 \111\098\115\101\114\118\097\098\108\101")n:GiveTask(r:Subscribe(p:GetFireFailComplete()))end,function()p:Complete()end))return n end)end end

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
