lua-users home
lua-l archive

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


I don't usually top-post, but excerpting Andrew's post would
distort it.

The two approaches are almost equivalent. If you don't
like an error being thrown, you can use pcall. If you want
an error to be thrown, you can use your own homebrewed
assert-like front-end to error. So ultimately it is a question
of taste. Someone who prefers to expunge "nil, error_msg"
from his code might as well order his Whopper with no
mayo and additional onions for all I care.

The way I program, I like to sanitize my input. User has
typed in something. Module says certain specs on its
parameters must be satisfied. Both are third-party, I am
in the middle. I don't trust the user to do it right, I don't
trust the module to behave gracefully. I check the input
myself and take appropriate action. That action may be
an immediate error exit, or it may be to continue reading
input and only eventually exiting.

Most of my own modules are designed to be used by me.
So they tend not to do any heavy input checking, and they
use neither "error" nor "pcall". Only when I contribute
something to LuaRocks (that's only one so far) do I put
those in.

Actually, at fast-food places, I never order a burger.


2014-09-18 6:18 GMT+02:00 Andrew Starks <andrew.starks@trms.com>:
>
>
> On Thu, Sep 11, 2014 at 12:41 AM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
>>
>> 2014-09-11 2:43 GMT+02:00 Rena <hyperhacker@gmail.com>:
>>
>> > The idiom I've heard and used is that returning (nil, errmsg) is for
>> > runtime errors, and error() is for programming errors. So e.g.:
>> > return nil, "Failed to open file: access denied"
>> > vs:
>> > error("Invalid argument to method frobulate (expected number)")
>>
>> The question one should ask is: could one reasonably expect
>> the calling routine have a nice way of recovering from this error?
>> If so, return nil,error_obj; otherwise abort.
>
>
> I've been thinking more about this topic.
>
> So, the above quote from the illustrious Dirk seems to be "what smart people
> do." That is, there is a consensus around this view.
>
> I don't think I understand it and I'm starting to think that "nil,
> error_msg" has no place in my code.
>
> The problem with `nil, error` is that "reasonably expect" is both unknowable
> and possibly irrelevant:
>
> 1: I'm chugging along and the user tries to access a resource that doesn't
> exist.
> 2: That can happen and it's hard to even call that an 'error'. It's a normal
> thing that *will* happen, maybe even often.
> 3: So, I decide to return nil, 404 "resource gone missin'"
>
> So what? I'm still not in that function call, any longer. I didn't do
> anything that pcall couldn't have handled, on the caller's end. If I do
> return nil, error, the caller has to trap it and deal with it, just the same
> as they would if they used pcall.
>
> And, chances are, they're going to return `nil, error_msg` right on up the
> stack and back to the user. Had I called error, then the caller could have
> chosen to let a caller up the stack trap it, presumably because they had
> more state to protect.
>
> In some contexts, 404 is an error. That is, it shouldn't happen. If I'm the
> one that's looking for the resource and I "know" that it is always there,
> then it's an assert from the callers end, if nil, err. Otherwise, if I don't
> do `nil, error`, then I don't use `pcall`, either. That seems pretty simple.
>
> If I use error, then I'm at risk of bailing out of my program, everywhere
> that I  'forget' to `pcall` something. Is that worse than forgetting to
> check for `nil, error`, silently accept `nil` as my return value and then
> carrying on as though all as well?
>
> Then there is the minor complexity of having two ways to receive an error.
> If I *know* that I don't want a call to barf, I have to use pcall because,
> while I can be careful not to use `error`, I call functions that might use
> it. So as the caller, if I use pcall to cover all cases, I now need to
> accept three return values, two of which are for errors: `success, value,
> err_msg`. Then I do the `if not (success and value) then return nil, success
> and err_msg or value end` dance.
>
> But I'm missing something that experience would have taught me. I'd love to
> hear an opposing rant that has been informed by it.
>
> -Andrew