From 9a248406b04d0e8942eaba38ff2828eae248e1ab Mon Sep 17 00:00:00 2001 From: Selt <83926739+seltonmt012@users.noreply.github.com> Date: Mon, 27 Jul 2026 16:18:57 +0200 Subject: [PATCH] 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. --- [core]/esx_lib/imports/points/client.lua | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/[core]/esx_lib/imports/points/client.lua b/[core]/esx_lib/imports/points/client.lua index 7fd04eb1..9c3790ca 100644 --- a/[core]/esx_lib/imports/points/client.lua +++ b/[core]/esx_lib/imports/points/client.lua @@ -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