Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

If a script has an error, can I make it restart?

Hey everyone! I was wondering if there was a way to make a script restart if there is an error? I'm not sure if there's a way or not, but if anyone knows, I would be thankful!

I'm thinking possibly writing a function that detects if the script has an error, then it disables and re-enables the script.

Thanks!

1 answer

✓ Accepted answer

Yes, pcall, it runs given function and returns if it errors without interrupting the script, only the calling function.

##Syntax

bool Success string? ErrorMesage pcall(func Func, tuple ...args)

It returns Success if function run successfully and error if the function errored. Here is examply of using it

local function Test()

	workspace:Destryo()
end

local Success, Response = pcall(Test)

print(Success, Response) -- false, Attempt to call a nil value

See the mistake? I had typo in the method but protected call prevented it from breaking the thread, you see i was able to print after the function.

pcalls also can have return values based off of the function return value, the order looks like this

  • Success
  • Function return arguments
  • Error

Function return arguments only exist if function will return something, take a look at this example

local function Get()

	return 'aaaa', 50
end

local Success, aaaa, number, Error = pcall(Get)

print(Success, aaaa, number, Error)
-- true
-- aaaa
-- 50
-- nil

Error is nil because the function did not error, which means it can't have error, if the function errors tho, the return arguments are always 2 because the function can't return anything, it stops, like in this example

local function Test()

	workspace:DesotriouyiASdujiosjdiofasd9sA()

	return 'aaaa'
end

local Success, aaaa, Error = pcall(Test)

print(Success, aaaa, Error)
-- false
-- Attempt to call a nil value gone wrong
-- nil

aaaa in this case is the error because the function crashed at line 3.

You can also call methods with pcall, since methods require : or self (i won't explain, too long) they need to be called with the self, but you can't do

pcall(workspace:ClearAllChildren)

Because after colon there always must be () no matter what, that's why you replace the function with this

pcall(workspace.ClearAllChildren, workspace)

workspace as the second argument as we want to clear that, with that you can do something like this

local Part = Instance.new('Part')

pcall(workspace.ClearAllChildren, Part)

This will clean all children of the part by calling method of workspace, cool right? no, ugly. Using aruments with method calls is the same, just like this

pcall(workspace.FindFirstChild, workspace, 'aaaa')

There is actually no reason to use pcall here. Pcalls are often used in Data stores where you want to get data but if roblox servers mess it up, you need to warn the gamer and even worse, not let him loose his data!

The best solution is to prevent any possible errors and mostly not make your script way too sensitive, e.g. doing this

local RunService = game:GetService('RunService')

local function OnRender()

end

RunService.Heartbeat:Connect(OnRender)

Is better than this

local RunService = game:GetService('RunService')

while (true)
do
	RunService.Heartbeat:Wait()
end

Because connections create new thread so it's better to have little detail causing error every frame than getting the whole script down, i would definitely not use while loop when i can use Connect.

Other good way of preventing scripts from breaking from errors is to use BindableEvents, you can connect your scripts/module scripts or whatever you use with signals which can be connected to functions so that will spawn a new thread, preventing some errors, good example would be for example you have loop and you want to loop through gamers to do something, you would fire bindable event instead of doing that in the loop because if gamer leaves and loop will be right at checking him, it will crash

local Players = game:GetService('Players')

local Signal = Instance.new('BindableEvent')

local function Kill(Character)

	Character.Humanoid.Health = 0
end

Signal.Event:Connect(Kill)

while (true)
do
	for _, Gamer in ipairs(Players:GetPlayers())
	do
		Signal:Fire(Gamer.Character)
	end

	wait(10)
end

You see no matter what, even if Character is nil, the function will error, but won't stop the loop, important notice; i used ipairs, it's similar to pairs but breaks when hits nil or number indexed or badly ordered index of value in the table, this will save you if gamer leaves in the loop, it will break the for loop but it will repeat in 10 seconds so better than breaking the whole script.

For your case, you can do

local Success = pcall(function()

	-- your script

end)

if not (Success)
then
	script.Disabled = true
	script.Disabled = false
end

But please no, use better methods. Pcall comes at a little performance cost and this is really not necessary.

Check these sources ###pcall ###Lua Globals with pcall ###BindableEvents

1 comment

0

Thank you so much! This is a better answer than anything I was hoping for :)

This discussion is preserved as it was. New answers, comments, and votes are closed.