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
local success, result = pcall(function()
validate(case.value, key, error)
validate(case.value, key)
end)
if case.expected and not success then

View file

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

View file

@ -29,21 +29,21 @@ local function isUnsafeTable(object: { [any]: any })
return false
end
local function validate(value: any, key: any, log: (string) -> ())
local function validate(value: any, key: any)
local typeOfKey = type(key)
local typeOfValue = type(value)
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
return log(`Invalid value type '{typeOfValue}' at key '{key}'`)
error(`Invalid value type '{typeOfValue}' at key '{key}'`)
elseif typeOfValue == "table" 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
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
return log(
error(
`Cannot sync tables unsupported by remote events! The value has the key '{key}'.\n\n`
.. "This can be for the following reasons:\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 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
return log(`Cannot sync infinity at key '{key}'`)
error(`Cannot sync infinity at key '{key}'`)
end
elseif typeOfKey == "number" 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
return log("Cannot sync non-integer number as key")
error("Cannot sync non-integer number as key")
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)