The error() function

Hey, I’ve checked out the error function and I’ve found its very useful for ‘breaking’ or stopping execution of the script if I can’t actually directly use the term break or return etc…

I’m wondering, is there a way to call ‘error()’ or use it to stop the script without actually having the script error popup on the Gmod UI? Alternatively, is there anything else I can use to stop the function without actually currently being in it.

Thanks.

MsgN and return

Sorry, to clarify - I meant, when you use the error function, it stops the execution, is there a way I can stop execution of the script like error (but without the message) from the outside where I can’t access return etc…

Where exactly is “the outside where you cannot access return”?

It sounds like you have bad code structure if you need to do something like that. Can you give a code example?

It is in the timeout for a loop restriction, basically using sethook, the timeout will be activated if a loop goes on for too long too quickly, but because of this I have a timeout function, if I return from that it does not break the loop, calling error() however ends execution and stops the loop. Because the timeout is not actually located inside the loop I cannot call break.

Could you provide specific code examples? Otherwise, you could try restructuring it to where you utilise the return to either break or continue the timer instead of relying on error.

Sure.



function sandbox.wrap(func, options)
	local options = options or {} -- Check options table
	local quota = options.quota or 250000 -- Check quota set
	local env = options.env or {} -- Check func environment
	local timeout_msg = options.msg or "Timeout generated function."

	setfenv(func, env) -- set function environment for passed 'func'

	return function(...)
	
		if(quota)then 
			local timeout = function() 
				debug.sethook()
				error(timeout_msg) < This stops execution of the dodgy loop
			end
			debug.sethook(timeout, "", quota)
		end

		local passed, result = pcall(func)
		debug.sethook()
		if not passed then error(result) end
		return result
	end
end

Whenever something (or nothing) is returned, the function scope stops.
You can just do a blank return in place of the error.

Thanks but I already tried that and it didn’t work.

You’re doing pcall() there anyway, just pass custom unique value to error() in timeout() and re-raise error only if error “message” doesn’t equal to your unique value. (In case you don’t know, you can pass ANYTHING to error(), not just strings)

Something about this is really wrong, but I have no idea what it is. error shouldn’t be used as a type of break/return. That’s just not what it is.

Well, there’s no other way to do it AFAIK. That guy basically needs to interrupt a function from another function, I’m not sure how else you’d do it.

Starfall uses same mechanism to interrupt running function from debug hook if execution time has exceeded allowed time: https://github.com/Mijyuoon/starfall/blob/master/lua/starfall/instance.lua#L43-L49

Actually it’s a very nice way to get out of functions and stuff, the fact that you can return any type with error and allows you to catch it using pcall.

Thanks mijyuoon, I think i might be misunderstanding what you’re saying because I’m not seeing how this will stop script execution. I’m using the error function to stop the script in its tracks, for instance:

if I passed a function to sandbox that was:


 for i=1,1000000000000 do print("LAG") end 

the debug.sethook is being used to detect if the loop amount is going over the ‘quota’, timeout is the function it calls if it does go over that limit, in that case, the function error is called where it will STOP the for loop, it just kills it off; my problem is that this generates a popup on the screen as expected, I would like to stop code like it does in the error function but without it generating the popup.

The issue is that you’re calling error from outside your protected call. This line:


if not passed then error(result) end

Because that error is unhandled by your script, gmod handles it and shows the error dialog.

[lua]local function some_func()
error(some_return_value)
end
iserror, ret = pcall(some_func, some, vars)[/lua]
[lua]local function some_func()
return some_return_value
end
ret = some_func()[/lua]

?

Edit: oh I think I get it, but slight restructuring would still easily solve this. e.g. return passed, result

Okay I see what you mean Neat thanks, and I see what you mean Willox; cheers.