7 min readCodocta

Débugger les erreurs Lua dans FiveM : Méthodes et outils essentiels

Guide complet pour identifier et corriger les erreurs Lua dans vos scripts FiveM. Techniques de debugging, outils recommandés, et solutions aux erreurs les plus courantes.

FiveMDebugLuaErreursDebuggingTroubleshooting
Partager :
Débugger les erreurs Lua dans FiveM : Méthodes et outils essentiels

Le debugging est une compétence essentielle pour tout développeur FiveM. Dans ce guide, nous allons voir comment identifier, comprendre et corriger les erreurs Lua dans vos scripts FiveM.

Types d'erreurs courantes

1. Erreurs de syntaxe

Les erreurs de syntaxe empêchent votre script de se charger :

-- ❌ Erreur : 'end' manquant
function maFonction()
    print("Hello")
-- Manque le 'end'

-- ✅ Correct
function maFonction()
    print("Hello")
end

2. Erreurs d'exécution

Ces erreurs se produisent pendant l'exécution du script :

-- ❌ Erreur : tente d'appeler une valeur nil
local x = nil
x()  -- CRASH: attempt to call a nil value

-- ✅ Correct : vérifier avant d'appeler
local x = nil
if x ~= nil then
    x()
end

3. Erreurs logiques

Le code s'exécute mais ne fait pas ce que vous voulez :

-- ❌ Erreur logique : condition inversée
if not isPlayerAdmin then
    giveAdminPowers()  -- Donne les pouvoirs aux NON-admins !
end

-- ✅ Correct
if isPlayerAdmin then
    giveAdminPowers()
end

Outils de debugging

Console F8

La console F8 est votre meilleur ami. Appuyez sur F8 dans le jeu pour voir :

  • Les messages print()
  • Les erreurs Lua
  • Les avertissements
  • Les commandes disponibles
-- Utiliser print() pour débugger
print("Valeur de x:", x)
print("Type de variable:", type(myVar))
print("^2[SUCCESS]^0 Opération réussie")  -- Couleurs dans la console
print("^1[ERROR]^0 Quelque chose a échoué")

Commande resmon

La commande resmon dans la console F8 montre :

  • L'utilisation CPU de chaque ressource
  • L'utilisation mémoire
  • Les ressources qui causent des ralentissements
# Dans la console F8
resmon

Logs serveur

Les erreurs côté serveur n'apparaissent pas dans la console F8. Regardez les logs serveur :

# Linux
tail -f /path/to/fivem/server.log

# Windows
# Regardez la console serveur directement

Techniques de debugging avancées

1. Fonction debug personnalisée

Créez une fonction de debug réutilisable :

-- utils.lua
Debug = {
    enabled = true
}

function Debug.log(...)
    if Debug.enabled then
        local args = {...}
        local str = "^3[DEBUG]^0"
        for i, v in ipairs(args) do
            str = str .. " " .. tostring(v)
        end
        print(str)
    end
end

function Debug.table(t, indent)
    if not Debug.enabled then return end

    indent = indent or 0
    local indentStr = string.rep("  ", indent)

    for k, v in pairs(t) do
        if type(v) == "table" then
            print(indentStr .. tostring(k) .. " = {")
            Debug.table(v, indent + 1)
            print(indentStr .. "}")
        else
            print(indentStr .. tostring(k) .. " = " .. tostring(v))
        end
    end
end

-- Utilisation
Debug.log("Joueur connecté", playerId)
Debug.table(playerData)

2. Try-Catch en Lua

Lua n'a pas de try-catch natif, mais on peut l'émuler :

function safeCall(func, ...)
    local success, error = pcall(func, ...)

    if not success then
        print("^1[ERROR]^0", error)
        return nil
    end

    return success
end

-- Utilisation
safeCall(function()
    -- Code potentiellement dangereux
    local result = dangerousOperation()
    print("Résultat:", result)
end)

3. Assertions

Utilisez des assertions pour vérifier les conditions :

function teleportPlayer(playerId, coords)
    assert(playerId ~= nil, "playerId ne peut pas être nil")
    assert(type(coords) == "table", "coords doit être une table")
    assert(coords.x ~= nil, "coords.x est requis")

    -- Code de téléportation
    SetEntityCoords(GetPlayerPed(playerId), coords.x, coords.y, coords.z)
end

-- Si une assertion échoue, le script crash avec un message clair

Erreurs courantes et solutions

Erreur : "attempt to call a nil value"

Cause : Vous essayez d'appeler une fonction qui n'existe pas.

-- ❌ Problème
myFunction()  -- myFunction n'est pas définie

-- ✅ Solution 1 : Définir la fonction
function myFunction()
    print("Hello")
end
myFunction()

-- ✅ Solution 2 : Vérifier avant d'appeler
if myFunction then
    myFunction()
end

Erreur : "attempt to index a nil value"

Cause : Vous essayez d'accéder à une propriété d'une variable nil.

-- ❌ Problème
local player = nil
print(player.name)  -- CRASH

-- ✅ Solution : Vérifier avant d'accéder
local player = nil
if player ~= nil then
    print(player.name)
end

-- ✅ Solution alternative : Opérateur and
local name = player and player.name or "Inconnu"

Erreur : "bad argument #X to 'Y'"

Cause : Vous passez le mauvais type de paramètre à une fonction.

-- ❌ Problème
SetEntityCoords(ped, "1000", "2000", "50")  -- Strings au lieu de numbers

-- ✅ Solution
SetEntityCoords(ped, 1000.0, 2000.0, 50.0)  -- Numbers

Erreur : Stack overflow

Cause : Récursion infinie ou boucle sans Wait.

-- ❌ Problème 1 : Récursion infinie
function recursive()
    recursive()
end

-- ✅ Solution : Ajouter une condition de sortie
function recursive(count)
    if count <= 0 then return end
    recursive(count - 1)
end

-- ❌ Problème 2 : Boucle sans Wait
Citizen.CreateThread(function()
    while true do
        -- Pas de Wait() !
        doSomething()
    end
end)

-- ✅ Solution : Ajouter un Wait
Citizen.CreateThread(function()
    while true do
        Citizen.Wait(1000)
        doSomething()
    end
end)

Debugging côté serveur

Logs détaillés

Ajoutez des logs pour tracer l'exécution :

-- server.lua
RegisterServerEvent('myScript:action')
AddEventHandler('myScript:action', function(data)
    print("^3[SERVER]^0 Événement reçu de", source)
    print("^3[SERVER]^0 Data:", json.encode(data))

    -- Traitement
    local result = processData(data)
    print("^3[SERVER]^0 Résultat:", result)

    TriggerClientEvent('myScript:response', source, result)
    print("^3[SERVER]^0 Réponse envoyée")
end)

Validation des données

Toujours valider les données reçues du client :

RegisterServerEvent('myScript:giveMoney')
AddEventHandler('myScript:giveMoney', function(amount)
    -- Validation
    if type(amount) ~= "number" then
        print("^1[ERROR]^0 Amount n'est pas un nombre:", type(amount))
        return
    end

    if amount <= 0 or amount > 10000 then
        print("^1[ERROR]^0 Amount invalide:", amount)
        return
    end

    -- Traitement sécurisé
    giveMoney(source, amount)
end)

Profiling des performances

Mesurer le temps d'exécution

function profileFunction(name, func, ...)
    local startTime = GetGameTimer()

    local result = func(...)

    local endTime = GetGameTimer()
    local duration = endTime - startTime

    print("^3[PROFILE]^0", name, "took", duration, "ms")

    return result
end

-- Utilisation
profileFunction("Heavy Calculation", function()
    -- Code à mesurer
    for i = 1, 100000 do
        math.sqrt(i)
    end
end)

Identifier les bottlenecks

-- Ajouter des timestamps dans votre code
local function debugTimestamp(label)
    print(string.format("^3[TIMESTAMP]^0 %s: %d ms", label, GetGameTimer()))
end

debugTimestamp("Start")
doSomething1()
debugTimestamp("After step 1")
doSomething2()
debugTimestamp("After step 2")
doSomething3()
debugTimestamp("End")

Outils externes

1. VS Code Extensions

  • vscode-lua : Coloration syntaxique
  • Lua Language Server : Autocomplétion et détection d'erreurs
  • FiveM Natives : Autocomplétion des natives FiveM

2. Linters

Utilisez un linter pour détecter les erreurs avant l'exécution :

# Installer luacheck
luarocks install luacheck

# Vérifier un fichier
luacheck mon-script.lua

Checklist de debugging

Quand vous avez une erreur :

  1. Lire le message d'erreur complet
  2. Identifier le fichier et la ligne
  3. Vérifier la syntaxe (parenthèses, virgules, etc.)
  4. Ajouter des print() pour tracer l'exécution
  5. Vérifier les types de variables
  6. Tester avec des valeurs simples
  7. Isoler le problème (commenter des parties du code)
  8. Vérifier les dépendances (autres ressources)
  9. Redémarrer la ressource
  10. Consulter les logs serveur

Bonnes pratiques pour éviter les bugs

1. Toujours initialiser les variables

-- ❌ Mauvais
local x
print(x + 5)  -- nil + 5 = erreur

-- ✅ Bon
local x = 0
print(x + 5)  -- 0 + 5 = 5

2. Utiliser des types cohérents

-- ❌ Mauvais : mélange de types
local id = "123"
if id == 123 then  -- String vs Number, toujours false
    print("Match")
end

-- ✅ Bon : types cohérents
local id = 123
if id == 123 then
    print("Match")
end

3. Documenter votre code

--- Téléporte un joueur aux coordonnées spécifiées
-- @param playerId number L'ID du joueur
-- @param coords table Les coordonnées {x, y, z}
-- @return boolean true si réussi, false sinon
function TeleportPlayer(playerId, coords)
    if not playerId or not coords then
        return false
    end

    SetEntityCoords(GetPlayerPed(playerId), coords.x, coords.y, coords.z)
    return true
end

Conclusion

Le debugging est une compétence qui s'améliore avec la pratique. N'ayez pas peur des erreurs, elles font partie du processus d'apprentissage. Avec les outils et techniques présentés dans ce guide, vous serez capable de résoudre la majorité des problèmes que vous rencontrerez.

Besoin d'aide pour débugger un problème complexe ? Notre équipe d'experts peut vous aider. Rejoignez notre Discord pour obtenir de l'aide !

Articles similaires

Cet article vous a été utile ?

Rejoignez notre communauté Discord pour poser vos questions et échanger avec d'autres développeurs FiveM.

Rejoindre le Discord