refactor: catch validation error with pcall

This commit is contained in:
Richard 2024-02-29 21:58:04 -08:00
parent d8d0c2a1f8
commit a30293ee3b
4 changed files with 22 additions and 59 deletions

View file

@ -17,7 +17,7 @@ return function()
for key, case in pairs(cases) do for key, case in pairs(cases) do
local success, result = pcall(function() local success, result = pcall(function()
validate(case.value, key, error) validate(case.value, key)
end) end)
if case.expected and not success then if case.expected and not success then

View file

@ -18,11 +18,17 @@ local function diff(previousState: { [any]: any }, nextState: { [any]: any })
end end
if _G.__DEV__ then if _G.__DEV__ then
for key, value in previousState do local success, result = pcall(function()
validate(value, key, warn) for key, value in previousState do
end validate(value, key)
for key, value in nextState do end
validate(value, key, warn) for key, value in nextState do
validate(value, key)
end
end)
if not success then
warn(result)
end end
end end

View file

@ -29,21 +29,21 @@ local function isUnsafeTable(object: { [any]: any })
return false return false
end end
local function validate(value: any, key: any, log: (string) -> ()) local function validate(value: any, key: any)
local typeOfKey = type(key) local typeOfKey = type(key)
local typeOfValue = type(value) local typeOfValue = type(value)
if not SAFE_KEYS[typeOfKey] then if not SAFE_KEYS[typeOfKey] then
return log(`Invalid key type '{typeOfKey}' at key '{key}'`) error(`Invalid key type '{typeOfKey}' at key '{key}'`)
elseif not SAFE_VALUES[typeOfValue] then elseif not SAFE_VALUES[typeOfValue] then
return log(`Invalid value type '{typeOfValue}' at key '{key}'`) error(`Invalid value type '{typeOfValue}' at key '{key}'`)
elseif typeOfValue == "table" then elseif typeOfValue == "table" then
if getmetatable(value) ~= nil then if getmetatable(value) ~= nil then
return log(`Cannot sync tables with metatables! Got {value} at key '{key}'`) error(`Cannot sync tables with metatables! Got {value} at key '{key}'`)
elseif isAtom(value) then elseif isAtom(value) then
return log(`Cannot sync nested atoms! Got atom '{value.debugLabel}' at key '{key}'`) error(`Cannot sync nested atoms! Got atom '{value.debugLabel}' at key '{key}'`)
elseif isUnsafeTable(value) then elseif isUnsafeTable(value) then
return log( error(
`Cannot sync tables unsupported by remote events! The value has the key '{key}'.\n\n` `Cannot sync tables unsupported by remote events! The value has the key '{key}'.\n\n`
.. "This can be for the following reasons:\n" .. "This can be for the following reasons:\n"
.. "1. The object is an array with non-sequential keys\n" .. "1. The object is an array with non-sequential keys\n"
@ -55,15 +55,15 @@ local function validate(value: any, key: any, log: (string) -> ())
if typeOfValue == "number" then if typeOfValue == "number" then
if value ~= value then if value ~= value then
return log(`Cannot sync NaN at key '{key}'`) error(`Cannot sync NaN at key '{key}'`)
elseif value == math.huge or value == -math.huge then elseif value == math.huge or value == -math.huge then
return log(`Cannot sync infinity at key '{key}'`) error(`Cannot sync infinity at key '{key}'`)
end end
elseif typeOfKey == "number" then elseif typeOfKey == "number" then
if key == math.huge or key == -math.huge then if key == math.huge or key == -math.huge then
return log("Cannot sync infinity as key") error("Cannot sync infinity as key")
elseif math.floor(key) ~= key then elseif math.floor(key) ~= key then
return log("Cannot sync non-integer number as key") error("Cannot sync non-integer number as key")
end end
end end
end end

View file

@ -1,43 +0,0 @@
local Players = game:GetService("Players")
local Charm = require(script.Parent)
local remotes: any = nil
local todoCount = 3
local todos = Charm.atom({
{ id = 1, text = "Learn about Charm" },
{ id = 2, text = "Build an app" },
{ id = 3, text = "Profit" },
})
local function addTodo(text)
todoCount += 1
todos(function(state)
local newState = table.clone(state)
table.insert(newState, { id = todoCount, text = text })
return newState
end)
end
local client = Charm.sync.client({
atoms = { todos = todos },
})
remotes.init:fire()
remotes.sync:connect(function(payload)
client:sync(payload)
end)
local server = Charm.sync.server({
atoms = { todos = todos },
})
server:onSync(function(player, payload)
print(player.Name, "synced", payload)
end)
Players.PlayerAdded:Connect(function(player)
server:hydrate(player)
end)