From a30293ee3b53e09616676ed3cdffa3c611f93b20 Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 29 Feb 2024 21:58:04 -0800 Subject: [PATCH] refactor: catch validation error with pcall --- src/__tests__/sync/validate.spec.luau | 2 +- src/sync/patch.luau | 16 ++++++---- src/sync/validate.luau | 20 ++++++------- src/test.luau | 43 --------------------------- 4 files changed, 22 insertions(+), 59 deletions(-) delete mode 100644 src/test.luau diff --git a/src/__tests__/sync/validate.spec.luau b/src/__tests__/sync/validate.spec.luau index 780bf84..934ec15 100644 --- a/src/__tests__/sync/validate.spec.luau +++ b/src/__tests__/sync/validate.spec.luau @@ -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 diff --git a/src/sync/patch.luau b/src/sync/patch.luau index 2dca41a..8827645 100644 --- a/src/sync/patch.luau +++ b/src/sync/patch.luau @@ -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 diff --git a/src/sync/validate.luau b/src/sync/validate.luau index f76e8cd..1005984 100644 --- a/src/sync/validate.luau +++ b/src/sync/validate.luau @@ -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 diff --git a/src/test.luau b/src/test.luau deleted file mode 100644 index 60c661b..0000000 --- a/src/test.luau +++ /dev/null @@ -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)