FiveM json.decode hatası: nil, boş dize ve geçersiz JSON düzeltmeleri

json.decode, FiveM komut dosyanızda başarısız olur veya nil döndürür mü? nil, boş veya elle düzenlenmiş JSON kodunun çözülmesinin neden kırıldığı, json.encode'un karışık anahtarlarla ne yaptığı ve pcall'ı güvenli bir şekilde nasıl kullanacağı.

Hata çözülmeden sonraki bir satırda görünür:

text
SCRIPT ERROR: @my_script/server/main.lua:31: attempt to index a nil value (local 'data')
lua
local data = json.decode(row.metadata)
print(data.level)   -- data is nil

json.decode size kullanılabilir bir şey vermedi, bu nedenle sonraki satır nil dizinine erişti. Çözüm nadiren gerçek hatadır. Giriş nil, boş veya kırıldı ya da daha önce kaydettiğiniz tablo düşündüğünüz şey değildi. İşte nasıl bulacağınız ve güvenli bir şekilde nasıl çözeceğiniz.

1. Dize nil veya boştur

En yaygın durum. Çözdüğünüz değer henüz yok:

  • NULL olan bir veritabanı sütunu. Kaydedilen verisi olmayan bir satır, o sütun için nil döndürür.
  • Sonuç olmayan bir sorgu. MySQL.scalar.await(...) ve MySQL.single.await(...) hiçbir satır eşleşmediğinde nil döndürür. Her işlevin ne döndürdüğü hakkında bilgi için oxmysql sorguları kılavuzu bölümüne bakın.
  • Asla ayarlanmamış bir KVP anahtarı. GetResourceKvpString('my_key') anahtar olmadığında nil döndürür; FiveM kaynak KVP bölümüne bakın.
  • Eksik bir dosya. LoadResourceFile(GetCurrentResourceName(), 'data.json') dosya yoksa nil döndürür.
  • Boş bir dize. '' olarak kaydedilen sütun da geçerli JSON değil.

nil veya '' kodunu çözmek arayanın hatasıdır, bu nedenle dizeyi önce kontrol edin:

lua
local raw = GetResourceKvpString('my_key')
local data = {}

if raw and raw ~= '' then
    data = json.decode(raw) or {}
end

2. JSON geçersizdir

Mevcut olan bir dize yine de geçersiz olabilir. Elle düzenlenmiş dosya veya veritabanı değeri olduğunda tipik nedenler:

  • Son girdiden sonra sondaki virgül: { "a": 1, }
  • Çift tırnak yerine tek tırnak: { 'a': 1 }
  • Yorumlar dosyada. JSON bunlara izin vermez.
  • Bir dosyanın bir kısmını kopyaladıktan sonra eksik parantez veya tırnak.
  • Lua söz dizimi bir JSON dosyasına yapıştırıldı; örneğin a = 1 veya [1] = 'x'.
  • Bir metin düzenleyicisinden bozuk karakter; örneğin web sayfasından kopyalanan kıvırcık tırnaklar.
json
{
  "items": [
    { "name": "water", "count": 2 },
    { "name": "bread", "count": 1 }
  ]
}

Komut dosyayı suçlamadan önce dosyayı doğrulayın. VS Code, yazarken JSON hatalarını altını çizerek gösterir ve çevrimiçi JSON doğrulayıcı hatanın tam konumunu gösterir.

3. Her zaman pcall ile çözün

Girişe ve yapıya bağlı olarak, kötü bir dize ya Lua hatası verir ya da nil olarak geri gelir. Hangisinin olduğunu hatırlamanız gerekmez: çağrıyı ikisinin de işlenmesi için sarın.

lua
local function safeDecode(str)
    if type(str) ~= 'string' or str == '' then
        return nil
    end

    local ok, result = pcall(json.decode, str)
    if not ok or type(result) ~= 'table' then
        return nil
    end

    return result
end

local data = safeDecode(row.metadata) or {}
print(data.level)

type(result) ~= 'table' kontrolü de "hello" veya 5 gibi geçerli JSON olan ancak nesne olmayan bir değeri yakalar.

İpucu: çözülme başarısız olduğunda ve nedenini bilmediğinizde, ham dizeyi türünün yanında yazdırın: print(type(str), str). nil veya boş bir satır nedeni hemen gösterir.

4. json.encode ve değişen anahtarlar

Çözülme çalışabilir ve yine de size yanlış veri verebilir, çünkü tablo gidiş-dönüş yolculuğundan kurtulamayan bir form halinde kaydedildi. JSON iki şekle sahiptir: bir liste [...] ve metin anahtarları olan bir nesne {...}.

lua
local saved = json.encode({ [100] = 'a', [250] = 'b' })
local loaded = json.decode(saved)

print(loaded[100])     -- nil
print(loaded['100'])   -- 'a'

Bu pratik anlamda ne anlama gelir:

  • Sayısal anahtarlar metin anahtarlarına dönüşür tablo nesne olarak kaydedildiğinde. Çözülmeden sonra değeri metin anahtarı ile arayın veya tonumber ile anahtarı dönüştürün.
  • Boşluklu seyrek diziler ({ [1] = 'a', [3] = 'c' }) temiz bir liste değil, bu nedenle bir dizi yerine nesne olarak yazılabilir.
  • Karışık tablolar, hem liste öğeleri hem de adlandırılmış anahtarlar ile, her iki şekle de temiz bir şekilde eşlenemez. Listeyi liste olarak tutun ve adlandırılmış alanları ayrı bir tabloya koyun.
  • İşlevler, userdata ve vektörler düz JSON verisi olarak yazılamaz. Kodlamadan önce vektörü { x = v.x, y = v.y, z = v.z } olarak dönüştürün.
  • Boş tablo genellikle [] olarak yazılır, bu nedenle nesne olarak değil, liste veya boş tablo olarak geri okuyun.

Koordinatları depolamanın güvenli bir yolu:

lua
-- save
local payload = json.encode({ x = coords.x, y = coords.y, z = coords.z })

-- load
local pos = safeDecode(payload)
if pos then
    SetEntityCoords(ped, pos.x, pos.y, pos.z, false, false, false, false)
end

Hata ayıklama sırasında json.encode(value, { indent = true }) kullanın, çünkü okunması çok daha kolaydır.

5. Bir kez çözün ve türü kontrol edin

Veritabanından gelen veriler, bir yerde dize olarak ve başka bir yerde tablo olarak komut dosyanıza ulaşabilir. Bazı kütüphaneler ve çerçeveler JSON sütunlarını sizin için çözer, diğerleri ham metni döndürür. Çözmeden önce ne tuttuğunuzu kontrol edin:

lua
local meta = row.metadata
if type(meta) == 'string' then
    meta = safeDecode(meta)
end
meta = meta or {}

Zaten tablo olan bir şeyi çözmek bir hatadır ve bir tür kontrolü hiçbir şeye mal olmaz.

Kontrol listesi

Belirti Çözüm
Çözmeden sonra attempt to index a nil value (local 'data') Dize nil veya geçersizdi; çözmeden önce kontrol edin ve pcall kullanın
Veritabanı sütunu çözülüyor NULL ve satır yok sonuçları nil'dir; if raw and raw ~= '' ile korunun
KVP okuması hiçbir şey vermiyor Anahtar asla ayarlanmadı; varsayılan tablo kullanın
Elle düzenlenmiş dosya başarısız olur Sondaki virgülleri, yorumları ve tek tırnak işaretlerini kaldırın; editörde doğrulayın
Çözülmeden sonra sayı anahtarları kaybolur JSON anahtarları metindir; t['100'] okuyun veya tonumber ile dönüştürün
JSON olarak yazılmış vektörler x, y ve z ayrı alanlar olarak kaydedin

Kısa yanıtlar

json.decode neden nil döndürür veya hata verir?

Dize nil, boş veya geçerli JSON değil. Duruma bağlı olarak hata verir veya hiçbir şey döndürmez, bu nedenle çağrıyı pcall ile sarın ve sonucu kontrol edin.

json.decode'dan sonra neden sayısal anahtarlarım dize oluyor?

JSON nesne anahtarları her zaman metindir. { [100] = true } gibi bir tablo, metin anahtarı 100 ile bir nesne olarak kaydedilir ve '100' anahtarı ile geri gelir, bu nedenle data[100] nil'dir.

Bir JSON dosyasının geçerli olup olmadığını nasıl kontrol edebilirim?

VS Code'da açın; bu editörde JSON hatalarını işaretler veya çevrimiçi JSON doğrulayıcısına yapıştırın. Olağan hatalar sondaki virgül, tek tırnak veya yorumdur.

Bu sorunu yaşatmayan scriptler

Item Creator V2Animasyonlar, proplar, efektler ve daha fazlasıyla kullanılabilir eşyalar oluşturun — kod yazmadan.Scripti gör →Shop CreatorBir dakikadan kısa sürede dükkân kurun — sahipler, çalışanlar, kasalar ve soygunlar dahil.Scripti gör →Quest CreatorGörevler ve NPC diyalogları için oyun içinde düğüm düğüm kurulan görsel editör.Scripti gör →

Okumaya devam edin