lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

I have been using an exception mechanism in LuaSocket that helped
simplify a lot the code. It will be available in the beta 2 release
probably next week. The functionality *is* already in Lua, but it's
often overlooked.

The main idea is that all functions should return nil followed
by an error message in case of failure. That way, you can nest
function calls with "assert"

    local c = assert(socket.connect("localhost", 80))

If connect fails, an exception is raised. Because it is sometimes
necessary to invoke some cleanup code before unrolling the stack, I have
been using something slightly more sophisticated:

    -- create a new "assert"-like function that calls a finalizer
    -- before throwing the exception
    -- this specific finalizer simply closes the socket
    local try = newtry(function() c:close() end)
    try(c:send("GET / HTTP/1.0\r\n\r\n"))
    local status = try(c:receive())
    ...

The only difference between assert and the "try" function returned by
"newtry" is that "try" calls the finalizer and doesn't mess with
the error message in case of error (assert might add the line number).

To complete the toolkit, I have a "protect" function that can be used to
wrap a function that throws exceptions into a function that simply
returns nil followed by the error message. This is used to protect the
final user from the errors raised by "try".

    -- the protected function never catches exceptions and returns
    -- nil followed by the error that was raised.
    get = protect(function(url)
        -- do stuff that calls "try" and can throw exceptions
    end)

The "protect" function is a simpler version of "pcall", of course.  The
two functions, "newtry" and "protect", take less than 35 lines of C code.
I promised to write a tiny LTN about it last week , but I didn't find
the time yet.

Hope it helps,
Diego.