Skip to content

Instantly share code, notes, and snippets.

@cwarden
Created September 9, 2011 23:06
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save cwarden/1207556 to your computer and use it in GitHub Desktop.
Save cwarden/1207556 to your computer and use it in GitHub Desktop.
require "try-catch"
try {
function()
error('oops')
end,
catch {
function(error)
print('caught error: ' .. error)
end
}
}
function catch(what)
return what[1]
end
function try(what)
status, result = pcall(what[1])
if not status then
what[2](result)
end
return result
end
@StarveTheEgo
Copy link

idiot

@Filgs
Copy link

Filgs commented Mar 14, 2020

Sensational idea !!
This is my suggestion to include "finally" in a different style approach:

_G["try"] = function (tab, ...)
  local ok, res, err = pcall(tab.try, ...) -- function tab.try may use:  return nil, 'error message'

  if not ok or not res then --catch both: Lua execution or logical errors
    ok, res = false, res or err or 'Error' -- adjust ok and res
    if tab.catch then
      if type (res) == 'string' then
        res = res:match ('.lua:%d+: (.*)') or res -- option to remove Lua line info
      end
      tab.catch (res, ...)
    end
  end

  if tab.finally then tab.finally (ok, res, ...) end
  return ok, res -- just 2 standard outputs
end

----------------------------------------
-- this is just an usage example
local myTask = {
  try = function(arg1, arg2, ...)
    assert (arg1 ~= 'p1', 'err1')
    assert (arg2 ~= 'p2', 'err2')

    if arg1 == 'foo' then error ('arg1 is foo') end
    if arg2 == 'bar' then return nil, 'arg2 is bar' end
    return 'OK'
  end,

  catch = function(res, ...)
    print('caught error: ' .. res)
  end,
  
  finally = function(ok, res, ...)
    print (string.format ('closing: %s', ok and 'success' or res))
  end
}

-- simple call usage
try (myTask, 'p1', 'p2')

-- result analysis usage
local ok, res = try (myTask, 'foo', 'bar')
if not ok then print ('Error: '..res)
else print ('Passed: '..ok) end

@arkt8
Copy link

arkt8 commented Aug 14, 2021

Why not just use pcall() with error() inside in case of wrongs?
appears to be a much cleaner way than employ tables with functions to emulate this. I know, sometimes we feel comfortable with our language skills but know a language way to do things may be more efficient and resources friendly.

@Nico-Pergande
Copy link

how would it look like? @arkt8

@arkt8
Copy link

arkt8 commented Nov 17, 2022

ok, res = pcall(fn, arg1 ... argn)
if not ok then
  -- treat here the catch --
end
-- normal flow --

I had not benchmarked with your code, but using table members always lead to performance degrading when comparing with local variables. Also it is the main purpose of pcall.

@Nico-Pergande
Copy link

ok, res = pcall(fn, arg1 ... argn)
if not ok then
  -- treat here the catch --
end
-- normal flow --

I had not benchmarked with your code, but using table members always lead to performance degrading when comparing with local variables. Also it is the main purpose of pcall.

so I would print the res with error() in the catch if clause?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment