Execution failed for KVP (Bad Cast)

Issue

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?

print(GetResourceKvpInt("9c4tnyg6m3rv233few")) -- output: 0
print(GetResourceKvpString("r807r78tn23rd23")) -- output: nil

Sure, for JS/C# 0 will do the job but why not using the same “nothing” type for all 3 programming languages since 0 isn’t considered false in Lua

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.