Custom Event error handler
planned
Tapple Gao
Luau scripts have a lot more ways to crash than LSL scripts. I wrote this as a proof of concept on making LLTimers and LLEvents crash proof:
It might be nice if there was a function like
LLEvents:setDefaultErrorHandler(errorHandler)
that did the same thing the above code does, without needing to wrap/monkey patch anything.Log In
Tapple Gao
I wish we had scriptable access to the default slua error handler, so I could wrap my coroutines with it. It's similar to this function:
local function errorHandler(msg)
ll.Say(DEBUG_CHANNEL, debug.traceback(msg, 2))
end
except
- the traceback is not broadcast publicly on DEBUG_CHANNEL, only to the owner (this is not replicatable with ll.RegionSayTo(ll.GetOwner(), DEBUG_CHANNEL, msg); see the wiki's caveats
- the traceback is only visible to the owner if the script is modifiable. I could probably this using bit32.btest(ll.GetInventoryPermMask(ll.GetScriptName(), MASK_BASE), PERM_MODIFY. But I don't know if this logic matches what the sim does due to insufficient testing
I'd want to use the error handler like:
local function coroLoudWrap(f)
-- works the same as coroutine.wrap, but if the
-- coroutine has an unhandled error, print a stack
-- trace, just like how the main thread does
return function(...)
return coroutine.resume(coroutine.create(xpcall), f, errorHandler, ...)
end
end
Honestly, I also wish
coroLoudWrap
was a builtin function, or coroutine.wrap
took a second argument that enabled this behavior. I don't like how using coroutines breaks error trackbacks unless you're very careful. Error trackbacks should be the easy path, not the hard oneTapple Gao
very related: it would be nice if all events started in a coroutine so that I don't need to add that wrapper to every event handler.
putting all events in a coroutine would have the side effect of making exceptions nonfatal, since coroutines are implicitly pcalled
Tapple Gao
DetectedEvent might complicate coroutines by default, as it is currently backed by global state rather than instanced state, and thus won't survive a yield
H
Harold Linden
updated the status to
planned
Thanks! I already have plans for something like this, design TBD :)
Tapple Gao
I haven't structured my slua scripts around linkset data and lljson yet, but I plan to. I'm not sure how much code I want to spend verifying that my linkset data has a sane format vs just leaving it to some high-level code similar to the above that deletes the linkset data key if there ends up being a problem using it.
I'll probably write some sort of linkset data wrapper that works similar to python's with block. That would be a lot more specific than "what to do for general unhandled errors". This wrapper would probably solve most random crashes I can currently imagine, while I'm this early in my slua journey.