Error function level parameter does not work

I’m using error in my module with the level set to 2 so that the error position information points to the script not the module while the output window prints the correct position when I click on the error it does not take me to the correct position

image

clicking on the red text takes me to ModuleScript: Line 4 not Script: Line 3


-- ModuleScript

local module = {}

module.MyFunction = function()
	error("message", 2) -- output a error at level 2
end

return module
-- Script

local module = require(game.ServerStorage.ModuleScript)

module.MyFunction()

Instead of error(), use debug.traceback(). Instead of printing the function where the error was called, it’ll return a string of all the function calls up to a certain point. In your case, it seems like you want to use something like:

local funcCallTraceback = debug.traceback("message", 2)
print(funcCallTraceback)
-- or even
error(funcCallTraceback, 0)

instead of

error("message", 2)

See more here:

https://create.roblox.com/docs/reference/engine/libraries/debug#traceback

I get the same result with

local module = {}

module.MyFunction = function()
	local funcCallTraceback = debug.traceback("message", 2)
	error(funcCallTraceback, 0)
end

return module

image
clicking on the red text takes me to ModuleScript: Line 5 not Script: Line 3

This is currently a bug with the Output. I recommend submitting a bug report.

Try using the module like this:

local module = {}

module.MyFunction = function(msg,lvl)
	error(msg, lvl);
end

return module;

Then calling code is:

local module = require(game.ServerStorage.ModuleScript);

module.MyFunction("message",2);

This is currently a bug with the Output. I recommend submitting a bug report.

I don’t have permission to post into the bug reports forum and I have tried contacting ROBLOX but was not much help

Try using the module like this:

This module is going to be used by the ROBLOX community so I cant make them pass in the level and I’m not sure how this would solve the problem it would still go to the wrong place when clicking on the error

If you want the code not to break and stop execution then you will have to either roll out your own error handler, or use warn(msg,lvl) rather than error(msg,lvl), or disable “Debug Errors” in studio:

image

This wont prevent the error catcher from halting the code execution in the same script, but it wont stop other scripts or the remainder of the game from executing. I think this could be desired behaviour, in that an error stops potentially undefined code running in the same script after the error is caught. If you have faith the error wont cause further segmentation faults in the remaining code in the script use warn() instead.

Who ever uses the module will decide if they want to halt on the errors but I don’t think you have understood the problem I’m trying to describe

When you click on the red text studio is not taking you to the correct location
it should take you to line 3 on the Script but instead studio is opening the ModuleScript and selecting line 4

this will give the users of the module the incorrect impression that the error happened inside the module when in fact the error is in there own script

The error happens whether it is handled or not, the code itself is not aware of errors unless they are well defined complier error (i.e. division by zero, square root of negative number,etc.). You have called error to tell yourself of the error so that is all the code can ever know, it can’t know the error source if it is not complier/mathematically defined. So the error location will always be where you tagged the failing, badly executed code from, i.e. the line it prints the error. In C++ the convention is to use try/catch blocks at the end of each function, but the code will always break on the error incidence if you want to farm-out the error handling to a class/struct (or in Lua’s case a Module). Generally you supply the line number and the function name, and the parameters that were passed to the erroring function. So an error handler would have inputs like this:

local module = {}

module.MyFunction = function(script_name,function_name,line_number,passed_string,error_lvl,params)
	local message = ("The script ".. script_name .. " called a function " .. function_name .. " on line " .. line_number .. " and returned the error " .. passed_string .. " with a severity level of " .. error_lvl .. " the supplied params were ");
	local param_string = "";
	for i = 1, #params do
		message ..= " " .. tostring(params[i]);
	end
	
	error(message, error_lvl);
end

return module;

Calling convention (this will still only report the error on the line within the module, but now you have info of the error source):

local module = require(game.ServerStorage.BadScript);

local function squareRoot(a)
	if a < 0 then module.MyFunction("Bad script","squareRoot",5,"Square root of negative number",2,{a}) end;
	return math.sqrt(a);
end

local function divideBy(a,b)
	if b == 0 then module.MyFunction("Bad script","divideBy",11,"Division by zero",2,{a,b}) end;
	return a/b;
end

squareRoot(-1);
divideBy(5,0);

Outputs have all the info you need as a programmer for debugging purposes:

image

image

lets say you do this

now I’m using CFrame incorrectly and I get a error when I click on that error it does not take me to the CFrame module it takes me to line 2 of my own script I want the same to happen in my module

if someone uses the module incorrectly the error should take them to level 2 not level 1 where the module throws the error

Unfortunately, you cant accommodate direct coding faux-pas like that. Code it badly and it will crash, not much you can do about bad callers. You simply don’t allow users to call functions directly. You have to roll-out your own functions and check the inputs before calling the CFrame.fromOrientation() function, i.e.:

local function makeCFrameXYZ(x:float,y:float,z:float) -- note: we tell the caller the required container by good variable naming conventions
if x == nil or y == nil or z == nil then module.MyFunction(nil supplied, blah blah blah) end;
if typeof(x) ~= 'float' or typeof(x) ~= 'integer' then module.MyFunction(incorrect container supplied for x,blah blah blah) end;
if typeof(y) ~= 'float' or typeof(y) ~= 'integer' then module.MyFunction(incorrect container supplied for y,blah blah blah) end;
-- etc.

-- further check on ranges of supplied values, i.e. nan, infinity, etc

-- ...

-- All good (fingers crossed) attempt to call underlying constructor
return CFrame.fromOrientation(x,y,z);
end

Or you can, if you feel empowered enough (not anything I would consider worth your time) roll-out a purpose-built scripting language of your own and fully handle syntax, calling convention, and secure private and public access functions, and their definitions with your own strict low-level error check system. But this is starting to sound like the murky territory of custom code compilation (shudder!)

Unfortunately I don’t think you have understood the problem I’m not looking for error checking

All I want is that when you click on a error inside the output window that studio will open the correct script and select the correct line

Then direct this to Roblox, for that is entirely their own error checking system, which I would say is the most robust and forgiving I have encountered, try coding in C++ and you will sometimes crash your entire computer. But, as I said before the code knows nothing of errors until you tell it. The error will always stem from the line you called ‘ERROR’ on. Unless it’s compiler defined (i.e. universally recognised as an impossibility, divide by zero, etc.) which means the code cannot continue without this being handled, what they call undefined behaviour, but undefined behaviour that is simply un-computable, “Computer says No” type stuff.

studio knows where the error is its right there in the message
image
script line 3 when I click that text studio should take me there

It all depends where segmentation takes place, you might get away with badly constructing a CFrame, as I said Roblox is highly forgiving for some of the worst errors anyone can make. But functions return values, they carry badly contained values in trust, and then they process them, often this processing is out of scope to the original source of the error. It is the nature of debugging. Most often the error happens, then 1000’s of instructions later the fault becomes unpassable to the next set of operations and it breaks there, i.e. nowhere near the actual error source. Often you will pick-up the error in a place you never thought it would have an effect.

They are using a similar tagging system that I showed you, script name, function, line etc. and they print it out when failure occurs. But it is out of scope, the error happened, it printed some values to you so you can fix it, this information is now outside the execution pathway, it has already run and it broke, and it is anyone’s guess on the CPU’s current execution state and the internal validity of the instruction set. They told you where the error happened, a click-on-link to take you to the error location is a feature request to be directed at Roblox and will probably require some neat saving of a local state log to pinpoint the unhandled, the keyword there, “UNHANDLED” usage faults.

here is a example how you can work out the instance and line the error needs to point to

local fullName, line = debug.info(2, "sl")
local names = fullName:split(".")
local instance = game
for i, name in names do instance = instance[name] end
testService:Error("message", instance, line)

but unfortunately testService:Error does not do anything when you click on the error

testService:Error is merely a mechanism for you to catch errors. I have already said the code doesn’t break and has knowledge of where it broke. If it breaks, the internal structure of the compiled code can now be considered as garbage, it has not the power to do the next instruction you tell it to, never mind asking it the last thing it did wrongly. The error is a reporting service, it is your job as a programmer to find the source of the error and fix it yourself.

The link you want to click on is now just a string printed out, it is information turned into a string, it has no other info attached, unless Roblox decide to parse the error string and implement a mechanism that searches your entire place for the named script, the named function, and the named line. What if the script copies it self to a different location on execution? You end the code running because it fails and the execution state is not the same as when the game is running, i.e. things get created and destroyed in different location, get copied around, by multiple players, how can you locate an object after it has been destroyed, not possible. The error is a highlighting system for you to figure out the issue.

if the string printed to the output is just a string how does that string open ModuleScript at line 4 when I click on it even after I have stopped playing the game?

if there was no other information attached to it then it would not be able to find ModuleScript line 4

Because Roblox must have something like I described implemented already, but it will only highlight a location that Roblox called the error() function itself, or when you did. The internal state of the executing code could now be impossible to parse and query in any meaningful way.

if it only highlights a location where the error() function is called itself then when you do CFrame.fromOrientation("TEST") then the error would point to the CFrame datatype and not the script that called the fromOrientation function but as we can see it does highlight the script that calls the fromOrientation function

image

so it should also be possible that when I click Script:3 it should open Script:3 and not ModuleScript:4