Exception handling

fendrin edited this page Apr 6, 2016 · 7 revisions

Although people might think that a modern language needs try/catch, the usual Lua pcall idiom is not as clumsy in MoonScript, especially if we specialize it for the case where the function return value is not important.

For example,

try = (f) ->
    ok,err = pcall f
    if not ok then err\gsub '^[^:]+:%d+: ',''

err = try ->
    print a.x
if err
    print 'error!',err

--~ error!  attempt to index global 'a' (a nil value)

An even more suggestive syntax can constructed, thanks to SelectricSimian:

try
    do: ->
        print a.x
    catch: (e) ->
        print 'error!',e
    finally: ->
        print 'gets here'

We are exploiting the fact that Moonscript allows a table with only key-value pairs to be specified without curly braces. The definition of try is very simple:

try = (t) ->
    ok,err = pcall t.do
    if not ok
        t.catch err
    t.finally! if t.finally

The simple implementation above still differs to what people are usually expecting regarding the finally function. finally is to be executed in all cases while our simple approach skips it in the case catch errors again. (Which is not that uncommon.)

This more complex version also returns the evaluated do or catch and thus can be used in assignments.

try = (t) ->
    -- ok, value = xpcall(t.do, errorHandler)
    ok, value = pcall(t.do)
    if ok
        t.finally! if t.finally
        return value
    else
        handled, backup_value = pcall(-> t.catch(value))
        t.finally! if t.finally
        if handled
            return backup_value
        else
            error(backup_value, 2)
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.