DEv0on

exceptional

May 13th, 2020
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.72 KB | None | 0 0
  1. local function getErrorData(errString)
  2.     local all, chunk, line, text = errString:match("^((.+):(%d+):%s(.+))$")
  3.     local exceptional, excepDetails = text:match("^(%[Exceptional%:(.+)%])$")
  4.     if all ~= nil and exceptional == nil then
  5.         --# It's a regular Lua error.
  6.         local details = {
  7.             ["Type"] = "LuaError",
  8.             ["Message"] = text,
  9.             ["Line"] = tonumber(line),
  10.             ["Chunk"] = chunk,
  11.             ["Plain"] = errString
  12.         }
  13.         return details
  14.     elseif all ~= nil and exceptional ~= nil then
  15.         --# It's an exception.
  16.         local details = textutils.unserialise(excepDetails)
  17.         details.Plain = errString
  18.         details.Line = tonumber(line)
  19.         details.Chunk = chunk
  20.         return details
  21.     else
  22.         --# Don't know how to handle it...
  23.         local details = {
  24.             ["Type"] = "Unknown",
  25.             ["Line"] = tonumber(line),
  26.             ["Chunk"] = chunk,
  27.             ["Plain"] = errString
  28.         }
  29.     end
  30. end
  31.  
  32. local function makeCatch(reqType, tbl, errData)
  33.     return function(self, catchFunc)
  34.         if (type(self) == "function" or type(self) == "table") and catchFunc == nil then
  35.             catchFunc = self
  36.         end
  37.  
  38.         if type(catchFunc) == "table" then
  39.             for _,v in pairs(catchFunc) do
  40.                 if type(v) == "function" then
  41.                     catchFunc = v
  42.                     break
  43.                 end
  44.             end
  45.         end
  46.  
  47.         if type(catchFunc) ~= "function" then
  48.             error("catch argument couldn't be resolved to a function!", 2)
  49.             return
  50.         end
  51.  
  52.         if reqType == nil or errData.Type == reqType then
  53.             catchFunc(errData)
  54.         end
  55.         return tbl
  56.     end
  57. end
  58.  
  59. local env = getfenv(0)
  60. env["try"] = function(f)
  61.     if f == nil then
  62.         error("throw argument couldn't be resolved to a function!", 2)
  63.     end
  64.  
  65.     local firstErr = nil
  66.  
  67.     if type(f) == "function" then
  68.         local ok, err = pcall(f)
  69.         if not ok then
  70.             firstErr = err
  71.         end
  72.     elseif type(f) == "table" then
  73.         for _,v in pairs(f) do
  74.             local ok, err = pcall(v)
  75.             if not ok then
  76.                 firstErr = err
  77.                 break
  78.             end
  79.         end
  80.     end
  81.  
  82.     local handled = {}
  83.  
  84.     if firstErr ~= nil then
  85.         --# There was an error!
  86.         return setmetatable({}, {
  87.             __index = function(t, k)
  88.                 if k == "catch" then
  89.                     k = nil
  90.                 end
  91.  
  92.                 if k ~= nil then
  93.                     handled[k] = true
  94.                 end
  95.  
  96.                 local errData = getErrorData(firstErr)
  97.                 if k == nil and handled[errData.Type] then
  98.                     return function() return t end
  99.                 end
  100.                 return makeCatch(k, t, errData)
  101.             end,
  102.  
  103.             __newindex = function() end
  104.         })
  105.     else
  106.         --# Don't care...
  107.         return setmetatable({}, {
  108.             __index = function(t, k)
  109.                 return function()
  110.                     return t
  111.                 end
  112.             end
  113.         })
  114.     end
  115. end
  116.  
  117. env["throw"] = function(msg)
  118.     if type(msg) == "string" then
  119.         error(msg, 2)
  120.     elseif type(msg) == "table" then
  121.         if msg.Type == nil then
  122.             error("throw table has no type!", 2)
  123.         end
  124.         error("[Exceptional:" .. textutils.serialise(msg) .. "]", 2)
  125.     end
  126. end
Add Comment
Please, Sign In to add comment