lua-users home
lua-l archive

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




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