570 posts
Posted 11 February 2015 - 01:59 PM
Exceptional adds an exception-style error handling system to Lua. If you've ever used a language with exceptions, you should be able to get familiar with the API fairly quickly.
Example usage:
os.unloadAPI(shell.resolve("exceptional"))
os.loadAPI(shell.resolve("exceptional"))
try {
function()
--# Is handled.
throw {
Type = "ItDoesntWorkError",
WhatDoesntWork = "It just doesn't work!"
}
--# These aren't actually called because throw terminates the function.
--# Throws a LuaError.
error("Some boring error.")
--# Is caught by the catch statement because it's unhandled.
throw {
Type = "SomeException"
}
--# If an exception doesn't have a handler and there is no catch statement,
--# the exception is suppressed completely.
end
} :LuaError {
function(e)
--# e is the exception table
printError("There was an error on line " .. e.Line .. " in chunk \"" .. e.Chunk .. "\"!")
printError("Details: " .. e.Message)
end
} :ItDoesntWorkError {
function(e)
printError("It doesn't work on line " .. e.Line .. " in chunk \"" .. e.Chunk .. "\"!")
printError("Details: " .. e.WhatDoesntWork)
end
} :catch {
function(e)
printError("Caught exception of type " .. e.Type .. " on line " .. e.Line .. " in chunk \"" .. e.Chunk .. "\"!")
end
}
Download:Pastebin linkor
pastebin get bfVk3qWR exceptional
The project is on GitHub now!
Edited on 12 February 2015 - 03:03 PM
1140 posts
Location
Kaunas, Lithuania
Posted 11 February 2015 - 03:23 PM
Very nice! :)/> Though you have to keep in mind that the error message may not always be a string. Also, the user might want to throw their own custom exceptions (classes, etc..).
570 posts
Posted 11 February 2015 - 03:31 PM
Very nice! :)/> Though you have to keep in mind that the error message may not always be a string. Also, the user might want to throw their own custom exceptions (classes, etc..).
Thank you! Currently, this is just a fancy interface for error/pcall, which only supports non-string errors from Lua 5.2 on. However, if I ever change how it works, I'll be sure to keep that in mind.
Edited on 11 February 2015 - 02:32 PM
1140 posts
Location
Kaunas, Lithuania
Posted 11 February 2015 - 03:42 PM
Thank you! Currently, this is just a fancy interface for error/pcall, which only supports non-string errors from Lua 5.2 on. However, if I ever change how it works, I'll be sure to keep that in mind.
Actually, Lua 5.1 supports any type of error message: strings, numbers, tables, functions, threads, userdata.
EDIT: Of course it's just a fancy interface, but it's really nice to have something like try-catch statement in Lua. pcall and error are not the best-looking ones.
Edited on 11 February 2015 - 02:44 PM
570 posts
Posted 11 February 2015 - 03:54 PM
Actually, Lua 5.1 supports any type of error message: strings, numbers, tables, functions, threads, userdata.
EDIT: Of course it's just a fancy interface, but it's really nice to have something like try-catch statement in Lua. pcall and error are not the best-looking ones.
Well, not quite. Lua just tostrings the input. error({ 1, 2, 3 }) gives me "table: [address]".
Regardless, I'll work on allowing you to specify an exception type using the throw function as well as catching exception types. Thinking about it, it sounds more complicated than it is so expect to see it soon :)/>.
1140 posts
Location
Kaunas, Lithuania
Posted 11 February 2015 - 06:46 PM
Well, not quite. Lua just tostrings the input. error({ 1, 2, 3 }) gives me "table: [address]".
Regardless, I'll work on allowing you to specify an exception type using the throw function as well as catching exception types. Thinking about it, it sounds more complicated than it is so expect to see it soon :)/>.
That's probably because you used 'print' which uses 'tostring' internally. Here, try this one:
local s, e = pcall(function()
error({test=123})
end)
print(e.test)
Anyway, good luck with exception types! :)/>
570 posts
Posted 12 February 2015 - 02:24 PM
That's probably because you used 'print' which uses 'tostring' internally. Here, try this one:
...
Anyway, good luck with exception types! :)/>
That's nil for me on CCEmuRedux and Minecraft. Are you perhaps using CCLite? Because strange things happen on CCLite.
Anyway, I've added them! Redownload the paste to get the update. Check the OP for example usage.
EDIT: You also no longer have to call exceptional.init and exceptional.cleanup. It's done automatically now.
Edited on 12 February 2015 - 03:03 PM
808 posts
Posted 12 February 2015 - 07:11 PM
Oh this could be fantastic with LuaLua. Having exception classes should be sweet. Could I include this with LuaLua? I could even add syntax similar to the table / string call syntax to make this even nicer considering the simplified anonymous function syntax already there.
try \()
throw ||MyException new| initWithMessage:"error!"|
end:LuaError \(e)
-- ...
end:MyException \(e)
-- ...
end
570 posts
Posted 12 February 2015 - 07:28 PM
Oh this could be fantastic with LuaLua. Having exception classes should be sweet. Could I include this with LuaLua? I could even add syntax similar to the table / string call syntax to make this even nicer considering the simplified anonymous function syntax already there.
…
Sure! I actually did want to make this for LuaLua at first because of its simplicity but decided to go with Lua to target a wider audience. But if you want to make a LuaLua version, I'm not stopping you. Good luck!
1140 posts
Location
Kaunas, Lithuania
Posted 12 February 2015 - 07:37 PM
Oh, custom exceptions look really really interesting. Good job! The LuaLua example also looks very nice.
BTW, about the 'error', looks like CC uses 'tostring' in 'error' but the actual Lua 5.1 doesn't and lets you pass any parameter. I tested that with LÖVE 2D, offline Lua 5.1 interactive interpreter (Ubuntu, apt-get package) and some online Lua 5.1 interpreters and they all allowed to pass any parameters to 'error'. I either am missing something here or the 'error' implementation in LuaJ is wrong. Could anyone confirm that?
570 posts
Posted 13 February 2015 - 07:48 PM
BTW, about the 'error', looks like CC uses 'tostring' in 'error' but the actual Lua 5.1 doesn't and lets you pass any parameter. I tested that with LÖVE 2D, offline Lua 5.1 interactive interpreter (Ubuntu, apt-get package) and some online Lua 5.1 interpreters and they all allowed to pass any parameters to 'error'. I either am missing something here or the 'error' implementation in LuaJ is wrong. Could anyone confirm that?
I seem to have figured it out…
print(type(({pcall(error, 1, 0)})[2]))
In ComputerCraft that code prints "string".
In Lua 5.1 it prints "number".
So yes, LuaJ's implementation is wrong. This is also backed up by
this (see bottom).
808 posts
Posted 13 February 2015 - 11:19 PM
Yea I started experimenting, and because of the way LuaLua objects work, they can't be properly thrown by this. Which is unfortunate. It'd be perfectly fine if not for this LuaJ bug =/