Client and server in depth · Lesson 2/4 · 8 min
Callbacks in depth and error handling
Callbacks return data from the server. Learn to pass several arguments and to never leave the client hanging.
You already saw callbacks in the frameworks module. Here we go a step further: multiple arguments, validation and always responding (a callback that never calls cb() leaves the client waiting forever).
-- Server: returns whether they can buy AND how much they have left
ESX.RegisterServerCallback('garaje:sacarCoche', function(source, cb, plate)
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return cb(false, 0) end -- ALWAYS respond
local coche = MySQL.single.await('SELECT * FROM owned_vehicles WHERE plate = ? AND owner = ?', { plate, xPlayer.identifier })
if not coche then return cb(false, 0) end
cb(true, xPlayer.getMoney())
end)Callback with validation
-- Client: receives the two values
ESX.TriggerServerCallback('garaje:sacarCoche', function(ok, dinero)
if ok then
print('Vehicle taken out. You have ' .. dinero .. '€ left')
else
print('That vehicle is not yours')
end
end, 'ABC123')Client
Rule: in ALL paths of the callback (including the early returns) you must call cb(). Otherwise, the client is left hanging waiting for the response.
Practice what you learned
0/3¿Qué pasa si un ESX.RegisterServerCallback hace un 'return' temprano sin llamar a cb()?
Pista
El cliente está esperando la respuesta del callback.
Completa el callback para que responda en TODOS los caminos y devuelva el dinero del jugador.
ESX.RegisterServerCallback('garaje:sacarCoche', function(source, cb, plate) local xPlayer = ESX.GetPlayerFromId(source) if not xPlayer then return (false, 0) end cb(true, xPlayer.())end)Pista
Incluso en el return temprano hay que llamar a cb(); el saldo se lee con getMoney().
Este callback deja al cliente colgado cuando el jugador no existe. Arréglalo para que responda en ese camino con cb(false).
Este código tiene un fallo:
ESX.RegisterServerCallback('licencia:tiene', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) if not xPlayer then return end cb(true)end)Reescríbelo corregido:
Pista
Cambia 'return end' por 'return cb(false) end'.
Challenge: code it yourself
Write a callback that checks if the player has a license (in the DB) and returns true/false + the license name.
Write it yourself in your editor (VS Code) and test it on your server. You learn here by doing it, not by copying.
See hint
MySQL.single.await + cb on every return, including the error case.
Escribe aquí tu solución:
