Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function a()
- print("A!")
- sleep(1)
- b()
- end
- function b()
- print("B!")
- error("Error in B!")
- end
- -- here be dragons
- local function buildStackTrace(rootErr)
- local trace = {}
- local i, hitEnd, _, e = 4, false
- repeat
- _, e = pcall(function() error("<tracemarker>", i) end)
- i = i + 1
- if e == "xpcall: <tracemarker>" or e == "pcall: <tracemarker>" then
- hitEnd = true
- break
- end
- table.insert(trace, e)
- until i > 10
- table.remove(trace)
- table.remove(trace, 1)
- if rootErr:match("^" .. trace[1]:match("^(.-:%d+)")) then table.remove(trace, 1) end
- local out = {}
- table.insert(out, rootErr)
- for i, v in ipairs(trace) do
- table.insert(out, " at " .. v:match("^(.-:%d+)"))
- end
- if not hitEnd then
- table.insert(out, " ...")
- end
- return table.concat(out, "\n")
- end
- local env = setmetatable({}, {__index=_ENV}) -- No need to override the runnign program
- env.pcall = function(f, ...)
- local args = { ... }
- return xpcall(function() f(unpack(args)) end, buildStackTrace)
- end
- env.xpcall = function(f, e)
- return xpcall(function() f() end, function(err) e(buildStackTrace(err)) end)
- end
- local f = setfenv(a, env)
- local function wrapper(func, args)
- local stack
- xpcall(function() func(unpack(args)) end,
- function(err)
- stack = buildStackTrace(err)
- end
- )
- if stack then error(stack, 0) end
- return true
- end
- local co = coroutine.create(wrapper)
- local ok, next = coroutine.resume(co, f, {})
- print(next)
- while ok and coroutine.status(co) ~= "dead" do
- e = {os.pullEvent()}
- if not next or e[1] == next or next == "" then
- ok, next = coroutine.resume(co, unpack(e))
- end
- end
- if not ok then
- printError(next)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement