Ive been trying to make a pcall retry function today and while I originally tried to do it with purely tuples (which failed) im not happy with my end result which involves a lot of table creation:
Here is my code:
local RetryPcall = {}
function RetryPcall.ActuallyTry(Function, Attempts, Arguments, ...)
if ... then
local Args = {...}
if Args[1] == true then
return select(2, ...)
end
elseif Attempts == 0 then
return
else
Attempts -= 1
end
return RetryPcall.ActuallyTry(
Function,
Attempts,
Arguments,
pcall(
Function,
table.unpack(Arguments)
)
)
end
function RetryPcall.Try(Function, Attempts, ...)
return RetryPcall.ActuallyTry(Function, Attempts, {...})
end
return RetryPcall
If anyone can think of a better way to do this please let me know, it may be obvious and im just not seeing it,
function repeatCall(callback, attempts, ...)
while attempts > 0 do
local success, result = pcall(callback, ...)
if success then
return result
end
attempts = attempts - 1
end
end
return function (callback, numAttempts, ...)
return repeatCall(callback, numAttempts, ...)
end
@HawDevelopment has given a function that retries a pcall until either it runs successfully or the code runs out of attempts in a smaller number of lines. You’ve just asked for a better way to do what the original code does, and as far as I can tell, the example given does it better.
You may not be aware, but pcall returns Success/Failure followed by at tuple of arguments. Their functions only return the first value of the tuple, not the entire tuple which as you can see from my original function is the intended behaviour.
function repeatCall(callback, attempts, ...)
while attempts > 0 do
local results = {pcall(callback, ...)}
if results[1] then -- No need for == true because it returns false if failed
return select(2, table.unpack(results))
end
attempts = attempts - 1
end
end
return function (callback, numAttempts, ...)
return repeatCall(callback, numAttempts, ...)
end