lua-users home
lua-l archive

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


On Sat, Sep 28, 2013 at 5:37 PM, Sean Conner <sean@conman.org> wrote:
    2. it  can be fixed, like EACCESS (bad privileges) or ELOOP (too many
       symbolic links when trying to resolve a filename) but that the fix
       has to happen outside the scope of the program, but once fixed, tends
       not happen again unless someone made a mistake;
[...]
    4. and finally, the small category of errors that a program might be
       able to handle, like ENOENT (file doesn't exist) depending upon the
       context (it could then create the file, or ask the user for a
       different file, etc.).

I feel like these are both the same category, really; in both cases the appropriate response is to somehow tell the user that there's a problem, and let them fix it. How you'll tell them depends on the program (show a dialog, write to stderr, write to a private log file and return an error page), and what they'll do to fix it is largely up to them (try another file, fix the broken symlinks, create the file, which might be done by a button on the error dialog), but in both cases the program handles it the same way: report the problem and abort the process (which might mean exiting the program, or just going back to the main loop waiting for another menu event, etc).

There are definitely some types of errors that represent a bug in the program or a problem with the system, that can't really be handled - maybe this is a good place to consider the distinction between using error() and returning nil and an error code - but even then, it's nice to report the problem to the user if you can, instead of just dying with no explanation. Lua's default handler does a good job of this if your program is normally used in a terminal, but printing to stderr isn't useful for GUI programs launched from a menu or desktop icon, where that text is just going to go nowhere, and the user is just going to be frustrated and confused why the program just quit suddenly. That's why some programs (and even Windows itself) have a crash report dialog, to tell the user there's something wrong with the program, so at least they know *something*.

This is one of those things that I liked about Java, though wasn't fond of the implementation (so much boilerplate and red tape!) - when anything goes wrong, you throw an exception; code further up the call stack can catch exceptions it knows how to deal with while letting the rest continue to bubble up. So you can catch "no such file" and "permission denied" exceptions (IO exceptions) right when you try to open a file, but let "out of memory" and "invalid argument to open" exceptions bubble up to an outer layer (perhaps the main loop) that can handle them more appropriately, by just informing the user (using whatever method is appropriate) that there's a problem with the program/system itself and shutting down.

To use this pattern in Lua, you have to use ugly syntax wrapping things in local ok, ex = pcall(function() ... end); if not ok then ... end; and you have to re-throw any error you can't handle right there, which adds another entire stack trace on, or discards it entirely if you aren't in an xpcall invocation.