lua-users home
lua-l archive

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



On Feb 16, 2006, at 22:44, Javier Guerra wrote:

On Thursday ١٦ February ٢٠٠٦ ٣:٢٩ pm, Chris wrote:
What is the proper way to do real error handling in Lua?

almost the only one who has done something constructive in this area is Diego
Nehab.  read this:

http://lua-users.org/wiki/FinalizedExceptions

this code is included in his luasocket package; but i think it shouldn't be
too hard to rewrite as a separate module

While overall I like Diego's paper, I'm confused by two aspects of it.

First, 'protect' returns a closure which encapsulate all the 'pcall' shebang. Couldn't 'protect' simply invoke the provided function directly?

function protect(f, ...)
        local ok, ret = pack(pcall(f, unpack(arg)))
        if ok then return unpack(ret)
        else return nil, ret[1] end
end

What are the benefits of encapsulating all this in an additional closure?

I'm also confused on how the 'newtry' finalizer could possibly work in the provided example:

    c = try(connect(host, 80))

Are not arguments evaluated before the function is invoked? Wouldn't 'connect' raise an exception before 'try' could even handle it? Shouldn't the example read more like this?

    c = try( function() return connect(host, 80) end )

Or is 'connect' already 'protected'? Confused :/

Anyhow, following Diego's lead, I hacked together my own little concoction. It goes something like this:

aService:try( "run", aContext )( catch )

'try' takes the name of the method to invoke, followed by its arguments. It returns a closure which take an optional error handler. Executing the closure returns the result of the method, or nil followed by the exception.

function self:try( aMethod, ... )
        local someArguments = { ... }
        local aLength = select( "#", ... )

        return function( catch )
                local aMethod = self[ aMethod ]
local someResults = { pcall( aMethod, self, unpack( someArguments, 1, aLength ) ) }
                local aStatus = someResults[ 1 ]

                if aStatus == true then
return unpack( someResults, 2, table.maxn( someResults ) )
                else
                        local anException = someResults[ 2 ]

                        if catch ~= nil then
catch( anException, self, aMethod, unpack( someArguments, 1, aLength ) )
                        end

                        return nil, anException
                end
        end
end

http://dev.alt.textdrive.com/browser/lu/LUObject.lua#L235
http://dev.alt.textdrive.com/browser/LW/LWApplication.lua#L147

While this, hmmm, works, it seems to be awfully convoluted for what it does :/

Looking forward to John Belmonte's "Exception Patterns in Lua" paper to bring some clarity to the issue :)

http://memebeam.org/john/lua/exception_patterns_abstract.html

Cheers

--
PA, Onnay Equitursay
http://alt.textdrive.com/