7 posts
Location
Basel, Switzerland
Posted 06 March 2014 - 12:55 AM
Hi everybody, lua -and- computercraft newbie here.
I'm dealing with the following simple code, executed in a turtle, which is derived from the last example in this page:
http://www.lua.org/pil/8.4.html
local status, err = pcall(function () error({code=121}) end)
print(status)
print(err)
print(err.code)
I'm confused by the result. Status is false, which make sense. But err is a string when I thought it'd be a table, and print(err.code) results in an empty line, consistent with err -not- being a table.
Am I doing something wrong or pcall does not return a table in ComputerCraft?
Manu
Edited on 07 March 2014 - 12:46 PM
7508 posts
Location
Australia
Posted 06 March 2014 - 02:25 AM
The problem isn't what
pcall returns, it's with what
error returns
1. ComputerCraft runs Lua 5.1 which
tostring's the message. Unfortunately the feature of being able to provide anything other than a string as the message was introduced in Lua 5.2
1 pcall can return anything, try the following code
local ok, val = pcall(function() return {code=301} end)
print(val.code)
Edited on 06 March 2014 - 01:27 AM
7 posts
Location
Basel, Switzerland
Posted 06 March 2014 - 08:40 PM
Thank you theoriginalbit for your answer!
Amazing how, having just started with lua, I managed to attempt to take advantage of one of the very latest features!
Concerning your workaround: my understanding is that the point of a pcall is that it catches errors and trigger special handling. I guess what you are saying is that if I want to do some error handling that includes passing back structured error information instead of a simple string I must bypass the error() function altogether. I.e. write functions that return an expected value or return something that can be interpreted and handled like an error by the calling function.
if(thereIsAnError) then
return {errorCode=301, errorLevel="PANIC!", message="You attempted to reboot the universe without saving. Don't do that again."}
else
return theExpectedNonTableValue
end
Am I understanding you correctly?
7508 posts
Location
Australia
Posted 06 March 2014 - 11:20 PM
-snip-
it wasn't so much a workaround, as it was a snippet to show that
pcall can return values.
I'd probably say the easiest method of dealing with the problem would be to just setup a variable to store error codes like so
local errorCode
local function foo()
errorCode = {code=301; level="PANIC"}
error("fatal error! what did you do?!")
end
local ok, err = pcall(foo)
if not ok then
print(err)
print("Code: ", errorCode and errorCode.code or "[missing data]")
print("Level: ", errorCode and errorCode.level or "[missing data]")
end
7 posts
Location
Basel, Switzerland
Posted 07 March 2014 - 01:34 PM
Of course! This way pcall still gets to do its job of catching errors while data about the error becomes available through the errorCode variable. Neat!
Also, to avoid potential conflicts or even store a history of errors, I guess I could do this:
local errorTable = {}
local function foo()
if (anErrorArises) then
errorTable[moreOrLessUniqueErrorKey] = {code=12; level="PANIC", message="Ouchy!!!"}
error(moreOrLessUniqueErrorKey)
else
return aValue
end
end
local ok, theReturnedValueOrAnErrorKey pcall(foo)
if not ok then
local errorObject = errorTable[theReturnedValueOrAnErrorKey ]
print(errorObject.code)
print(errorObject.level)
print(errorObject.message)
end
Thank you! Much appreciated!
Edited on 07 March 2014 - 12:37 PM
7508 posts
Location
Australia
Posted 07 March 2014 - 02:28 PM
Also, to avoid potential conflicts or even store a history of errors, I guess I could do this
well there shouldn't be conflicts unless you plan on dealing with coroutines. however if you wanted to do a history you could simply do this
local errorCode = {}
local function foo()
table.insert(errorCode, {code=301; level="PANIC"})
error("fatal error! what did you do?!")
end
local ok, err = pcall(foo)
if not ok then
print(err)
print("Code: ", errorCode[#errorCode].code or "[missing data]")
print("Level: ", errorCode[#errorCode].level or "[missing data]")
end