Setfenv; number expected, got table

Hi there, I am trying to output prints, warnings and errors into a table in my code editor I made. The issue is, is that I have used a getfenv, and setfenv to output of those within the sandbox environment, which throws an error saying invalid argument #1 to 'setfenv' (number expected, got table). I do not know what else to do as I am basically confused at this point since I returned the index in the metatable.

local outputlines = {}
	
	local scriptran = loadstring(text::string)

	local env = getfenv(scriptran)
	
	local sandbox = setmetatable({}, {
		__index = function(_,var)
			return env[var]
		end,
		print = function(...)
			table.insert(outputlines,(...))
		end,
		warn = function(...)
			table.insert(outputlines,(...))
		end,
		error = function(...)
			table.insert(outputlines,(...))
		end,
	})
	setfenv(env,sandbox)
	scriptran()
	
	for i,v in ipairs(outputlines) do
		print(v)
	end

Other way around. setfenv(FUNCTION, ENVIRONMENT).

Alright, is everything else correct?

Same error, says number expected, got table.

Wait I’m dumb you never even put the function in setfenv

setfenv(scriptran, sandbox)

Oh, I thought env was already the function here, I’ll try.

Nope, still same error except it says number expected, got nil

u sure?

I’m not 100% sure. atm, I’m trying to test if it receives errors and it gives me that error.

also I don’t think you even sandboxed the function correctly, the environment should go into the metatable, not the metamethod table

I’m not sure what I did wrong, could you paste your script here so I could try that instead?

oops I exited out of the tab with that

just copy it word for word ig

Alright here I go typing again lol.

Yeah I don’t know, I even pasted into studio console to test but same error saying number expected, got nil.

local outputlines = {}
	
	local scriptran = loadstring[[
		print("A")
		print
	]]

	local env = getfenv(scriptran)
	
	local sandbox = setmetatable({
		print = function(...)
			table.insert(outputlines,(...))
		end,
		warn = function(...)
			table.insert(outputlines,(...))
		end,
		error = function(...)
			table.insert(outputlines,(...))
		end,
	},{
		__index = function(_,var)
			return env[var]
		end,
	})
	setfenv(scriptran,sandbox)
	scriptran()
	
	for i,v in pairs(outputlines) do
		print(v)
	end

note I put a intentional error then to see if it inserts the error

That’s not how it works, the error function is for deliberate errors ran with the error() function
You need to use pcall to catch runtime errors

Oh, also I tested your exact loadstring and it seemed to work??

But if I try to print strings it doesn’t.

local Print, Warn = print, warn

local fenv = getfenv(0)
fenv.print = Warn
fenv.warn = Print
setfenv(0, fenv)

print("Hello world!") --Orange output.
warn("Hello world!") --White output.

Not sure exactly what you’re trying to achieve, would you mind explaining? In the snipper above I simply switched the functionality of the global ‘print’ and ‘warn’ functions.

1 Like

I have a custom code editor I made in my game, and along with that is output that is meant to receive prints, warnings and output just like the one in studio

Basically I want to receive output from my sandbox