mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 01:01:22 +00:00
fix(esx_lib/points): keep the points loop alive when a callback errors
Every point from every resource is served by one shared thread, and the enter, leave
and inside callbacks are all invoked bare. A Lua error in any one of them terminates
that coroutine, and nothing restarts it - startLoop only runs once, from the spawn
handler in es_extended.
So a single faulty third party resource takes down point detection for the whole
client. Shops, garages and job markers stop reacting, with no hint beyond one stack
trace, until the player reconnects.
inside is the worst of the three because it runs every frame while the player stands
in the point, so it is also dropped from insidePoints once it errors. Otherwise the
guard would turn a dead thread into a console flood at framerate. enter and leave only
fire on a transition, so they stay registered.
Measured in game on artifact 25770, with a healthy point, a point whose enter raises
and a point whose inside raises, all created while standing on them:
before: the healthy point fired enter, then the broken one raised at points/client.lua
and after that nothing happened at all - no leave when walking away, and
points created afterwards never fired enter either, the thread was gone
after: both failures are logged against the owning point and resource, all three
points fired leave when walking away, and points created afterwards worked
normally. The inside failure printed once rather than every frame.
The runtime already prints the error and its stack, so the added line only names the
point and the resource it came from.
This commit is contained in:
@@ -50,8 +50,11 @@ function xLib.points.startLoop()
|
||||
while true do
|
||||
local coords = GetEntityCoords(PlayerPedId())
|
||||
|
||||
for _, point in pairs(insidePoints) do
|
||||
point.inside(#(coords - point.coords))
|
||||
for handle, point in pairs(insidePoints) do
|
||||
if not pcall(point.inside, #(coords - point.coords)) then
|
||||
insidePoints[handle] = nil
|
||||
print(("[^1ERROR^7] point ^5%s^7 from ^5%s^7 errored on inside"):format(handle, point.resource))
|
||||
end
|
||||
end
|
||||
|
||||
local now = GetGameTimer()
|
||||
@@ -63,8 +66,8 @@ function xLib.points.startLoop()
|
||||
if not point.nearby then
|
||||
point.nearby = true
|
||||
|
||||
if point.enter then
|
||||
point.enter()
|
||||
if point.enter and not pcall(point.enter) then
|
||||
print(("[^1ERROR^7] point ^5%s^7 from ^5%s^7 errored on enter"):format(handle, point.resource))
|
||||
end
|
||||
|
||||
if point.inside then
|
||||
@@ -74,8 +77,8 @@ function xLib.points.startLoop()
|
||||
elseif point.nearby then
|
||||
point.nearby = false
|
||||
|
||||
if point.leave then
|
||||
point.leave()
|
||||
if point.leave and not pcall(point.leave) then
|
||||
print(("[^1ERROR^7] point ^5%s^7 from ^5%s^7 errored on leave"):format(handle, point.resource))
|
||||
end
|
||||
|
||||
insidePoints[handle] = nil
|
||||
|
||||
Reference in New Issue
Block a user