If you try to load an int value using GetResourceKvpString it will raise an error instead of returning nil
I know an 'easy fix' will be to check if there is any value in first place and delete it
if GetResourceKvpInt(key) ~= 0 then
DeleteResourceKvp(key)
end
-- but as soon as we set the key value to string and we run the above code,
-- same issue will happen so maybe using `pcall` it's a good idea
Repro
Citizen.CreateThread(function()
local kvp_keyword = GetCurrentResourceName() .. '_easy_boy'
-- **OLD code** --
-- KVP value already stored on client cache
SetResourceKvpInt(kvp_keyword, 99)
------------------
print(GetResourceKvpString(kvp_keyword))
end)
Error
Console output
Lua_InvokeNative: execution failed: bad cast
SCRIPT ERROR: Execution of native 000000005240da5a in script host failed: bad cast
> GetResourceKvpString (GetResourceKvpString.lua:6)
> fn (@repro_kvp_err_trace/client.lua:14)
Info
Client: Canary
Server: v1.0.0.3767 win32 OneSync
Also
Isn’t weird that int and string return different values when the actual value doesn’t exist?
It is using ‘the same “nothing” type’. An int can’t be nil though, only nil can be nil in Lua. This native returns int.
For char*, 0 is not a valid value, so it can be replaced with nil, but for int, 0 is valid, or would you prefer all integers that are 0 to return nil always?
Nope, in C# you can only if (boolean). Not any nullable (this needs == null), nor any integer (this needs == 0, and == null will lead to a compile-time error).
Finally,
What makes nil a more expected value compared to, say, the integer stringified?
You’re right, an integer stringified it’s a better solution than returning nil.
I was just expecting to get nil when you try to get an invalid type from a key-value pair with a data type already set.
I guess it’s because I’m more used to high-level languages where you don’t specify the data type like Lua, Python, Javascript and I don’t really think about the actual implementation or it’s just a personal opinion.
Besides my ‘easy fix’ approach I can also change the Kvp key to something new and it will solve the issue without any hustle which I already did it.
Question
In Lua how can we tell if an int kvp data exists or not - without using Start/Find/EndKvp functions?
It would be possible to create a _KVP_VALUE_TYPE native that returns the type (as a string?) of the decoded msgpack object associated with a given key.
Also, it may be beneficial to have all msgpack::unpack operations be wrapped in try/catch msgpack::unpack_error block that returns a null value and some console trace on error. This more cleanly handles the reported issue and prevents the SCRT from having to handle this exception.