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:
SCRIPT ERROR: @my_script/server/main.lua:31: attempt to index a nil value (local 'data')local data = json.decode(row.metadata)
print(data.level) -- data is niljson.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:
NULLolan bir veritabanı sütunu. Kaydedilen verisi olmayan bir satır, o sütun içinnildöndürür.- Sonuç olmayan bir sorgu.
MySQL.scalar.await(...)veMySQL.single.await(...)hiçbir satır eşleşmediğindenildö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ığındanildöndürür; FiveM kaynak KVP bölümüne bakın. - Eksik bir dosya.
LoadResourceFile(GetCurrentResourceName(), 'data.json')dosya yoksanildö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:
local raw = GetResourceKvpString('my_key')
local data = {}
if raw and raw ~= '' then
data = json.decode(raw) or {}
end2. 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 = 1veya[1] = 'x'. - Bir metin düzenleyicisinden bozuk karakter; örneğin web sayfasından kopyalanan kıvırcık tırnaklar.
{
"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.
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).nilveya 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 {...}.
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
tonumberile 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:
-- 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)
endHata 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:
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 →