lua-users home
lua-l archive

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


On Tue, Apr 28, 2015 at 8:33 AM, Andrew Starks <andrew.starks@trms.com> wrote:
> On Tuesday, April 28, 2015, Thijs Schreijer <thijs@thijsschreijer.nl> wrote:
>>
>>
>>
>> > -----Original Message-----
>> > From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
>> > Behalf Of Daniel Silverstone
>> > Sent: dinsdag 28 april 2015 12:33
>> > To: lua-l@lists.lua.org
>> > Subject: Re: clumsiness of pcall() syntax and how we deal with it
>> >
>> > On Tue, Apr 28, 2015 at 13:19:04 +0300, Konstantin Osipov wrote:
>> > > The first problem is in ambiguity of the second argument.
>> > > In case there is no error, it's the return value of the function.
>> > > Otherwise, it's a string with a message.
>> >
>> > I tend to use 'ok, result = pcall(xyz, blah)' and then:
>> >
>> > if ok then
>> >   ...use result as useful result...
>> > else
>> >   ...result is the error...
>> > end
>> >
>> > > How to name the second argument? And what if a function returns
>> > > multiple arguments?
>> >
>> > Multiple returns is a toughie and I will admit I tend not to use
>> > them in cases where I want to return errors too.  Then again I tend
>> > to code functions which return an ok, result tuple most of the time
>> > and then deal with wrappering them in assert() when I'd rather they
>> > threw an error.
>> >
>>
>> After recently having worked on http clients (with copas/luasocket/luasec) I have started to appreciate the luasocket functions protect, try and newtry for error handling.
>>
>> Thijs
>>
>>
>
>
> I'm processing media content in a graph and have the same need: a way
> to roll back partial changes when an error is thrown in a node.
>
> My model uses tables as objects and I've settled on wrapping xpcall like so:
>
>     do local xpcall = assert(xpcall)
>     function Resource:pcall(fun, ...)
>         return xpcall(fun, self.error_handler, self, ...)
>     end end
>
> This is still a work in progress. I'm deciding whether or not I want
> to have an 'on_error' function that wraps this one, so that a call
> would look like this:
>
>     local result, result2, etc = self:on_error(function()
>         --clean up state here
>     end)
>        :pcall(self.method, arg1,arg2)
>
> Right now, it works like pcall and I check the error after the
> function call. If it fails, I clean up and error again, except my
> error message is the error object that I got back from the prior
> xpcall. I pre-pend the new stack info to the original error message
> and the result is a pretty good idea of 'what happened'.
>
> Also, I include the object's `name` field in the error message, which
> has been surprisingly helpful when things are concurrent.
>
> Through this process, I have learned:
>
> 1: I have much to learn about errors and how to handle them.
> 2: Good programs have good errors.
> 3: Post error cleanup is hard and it's probably a good idea to start
> with the hardest part of that problem, first.
> 4: Lua's error handling facilities are actually pretty decent, as far
> as my limited experience is able to discern. Whenever I have thought
> that it was missing something, I realized that I could make it myself
> or that I really didn't want it in the first place.
> 5: This topic can descend into a debate over opinions very quickly. I
> like those, but others have a limited tolerance for them, most likely
> because they've already debated the topic and settled it in their own
> mind.
>
>
> One final point @Konstantin: In Lua, meta-programming is normal. That
> is, whatever it is that you want can be programmed into Lua and if it
> cannot, then it's probably worth discussion. But if it can, I doubt
> that it would get added. Too many people deal with errors in too many
> different ways.
>
> -Andrew
>

Speaking of meta-programming: There's always the option to introduce
try/catch/end syntax in a preprocessor. :P

/s/ Adam