start of error handling
This commit is contained in:
@@ -22,6 +22,7 @@ local LayoutEngine = req("LayoutEngine")
|
|||||||
local Renderer = req("Renderer")
|
local Renderer = req("Renderer")
|
||||||
local EventHandler = req("EventHandler")
|
local EventHandler = req("EventHandler")
|
||||||
local ScrollManager = req("ScrollManager")
|
local ScrollManager = req("ScrollManager")
|
||||||
|
local ErrorHandler = req("ErrorHandler")
|
||||||
|
|
||||||
-- Extract utilities
|
-- Extract utilities
|
||||||
local enums = utils.enums
|
local enums = utils.enums
|
||||||
@@ -211,6 +212,52 @@ Public API methods to access internal state:
|
|||||||
local Element = {}
|
local Element = {}
|
||||||
Element.__index = Element
|
Element.__index = Element
|
||||||
|
|
||||||
|
-- Validation helper functions
|
||||||
|
local function validateEnum(value, enumTable, propName, moduleName)
|
||||||
|
if value == nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, validValue in pairs(enumTable) do
|
||||||
|
if value == validValue then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Build list of valid options
|
||||||
|
local validOptions = {}
|
||||||
|
for _, v in pairs(enumTable) do
|
||||||
|
table.insert(validOptions, "'" .. v .. "'")
|
||||||
|
end
|
||||||
|
table.sort(validOptions)
|
||||||
|
|
||||||
|
ErrorHandler.error(moduleName or "Element", string.format("%s must be one of: %s. Got: '%s'", propName, table.concat(validOptions, ", "), tostring(value)))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function validateRange(value, min, max, propName, moduleName)
|
||||||
|
if value == nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if type(value) ~= "number" then
|
||||||
|
ErrorHandler.error(moduleName or "Element", string.format("%s must be a number, got %s", propName, type(value)))
|
||||||
|
end
|
||||||
|
if value < min or value > max then
|
||||||
|
ErrorHandler.error(moduleName or "Element", string.format("%s must be between %s and %s, got %s", propName, tostring(min), tostring(max), tostring(value)))
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function validateType(value, expectedType, propName, moduleName)
|
||||||
|
if value == nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local actualType = type(value)
|
||||||
|
if actualType ~= expectedType then
|
||||||
|
ErrorHandler.error(moduleName or "Element", string.format("%s must be %s, got %s", propName, expectedType, actualType))
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
---@param props ElementProps
|
---@param props ElementProps
|
||||||
---@return Element
|
---@return Element
|
||||||
function Element.new(props)
|
function Element.new(props)
|
||||||
@@ -292,7 +339,10 @@ function Element.new(props)
|
|||||||
self.passwordMode = props.passwordMode or false
|
self.passwordMode = props.passwordMode or false
|
||||||
|
|
||||||
-- Validate property combinations: passwordMode disables multiline
|
-- Validate property combinations: passwordMode disables multiline
|
||||||
if self.passwordMode then
|
if self.passwordMode and props.multiline then
|
||||||
|
ErrorHandler.warn("Element", "passwordMode is enabled, multiline will be disabled")
|
||||||
|
self.multiline = false
|
||||||
|
elseif self.passwordMode then
|
||||||
self.multiline = false
|
self.multiline = false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -375,6 +425,11 @@ function Element.new(props)
|
|||||||
}
|
}
|
||||||
self.borderColor = props.borderColor or Color.new(0, 0, 0, 1)
|
self.borderColor = props.borderColor or Color.new(0, 0, 0, 1)
|
||||||
self.backgroundColor = props.backgroundColor or Color.new(0, 0, 0, 0)
|
self.backgroundColor = props.backgroundColor or Color.new(0, 0, 0, 0)
|
||||||
|
|
||||||
|
-- Validate and set opacity
|
||||||
|
if props.opacity ~= nil then
|
||||||
|
validateRange(props.opacity, 0, 1, "opacity")
|
||||||
|
end
|
||||||
self.opacity = props.opacity or 1
|
self.opacity = props.opacity or 1
|
||||||
|
|
||||||
-- Handle cornerRadius (can be number or table)
|
-- Handle cornerRadius (can be number or table)
|
||||||
@@ -415,13 +470,28 @@ function Element.new(props)
|
|||||||
self.text = self._textBuffer
|
self.text = self._textBuffer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Validate and set textAlign
|
||||||
|
if props.textAlign then
|
||||||
|
validateEnum(props.textAlign, TextAlign, "textAlign")
|
||||||
|
end
|
||||||
self.textAlign = props.textAlign or TextAlign.START
|
self.textAlign = props.textAlign or TextAlign.START
|
||||||
|
|
||||||
-- Image properties
|
-- Image properties
|
||||||
self.imagePath = props.imagePath
|
self.imagePath = props.imagePath
|
||||||
self.image = props.image
|
self.image = props.image
|
||||||
|
|
||||||
|
-- Validate objectFit
|
||||||
|
if props.objectFit then
|
||||||
|
local validObjectFit = { fill = "fill", contain = "contain", cover = "cover", ["scale-down"] = "scale-down", none = "none" }
|
||||||
|
validateEnum(props.objectFit, validObjectFit, "objectFit")
|
||||||
|
end
|
||||||
self.objectFit = props.objectFit or "fill"
|
self.objectFit = props.objectFit or "fill"
|
||||||
self.objectPosition = props.objectPosition or "center center"
|
self.objectPosition = props.objectPosition or "center center"
|
||||||
|
|
||||||
|
-- Validate and set imageOpacity
|
||||||
|
if props.imageOpacity ~= nil then
|
||||||
|
validateRange(props.imageOpacity, 0, 1, "imageOpacity")
|
||||||
|
end
|
||||||
self.imageOpacity = props.imageOpacity or 1
|
self.imageOpacity = props.imageOpacity or 1
|
||||||
|
|
||||||
-- Auto-load image if imagePath is provided
|
-- Auto-load image if imagePath is provided
|
||||||
@@ -570,12 +640,12 @@ function Element.new(props)
|
|||||||
-- Pixel units
|
-- Pixel units
|
||||||
self.textSize = value
|
self.textSize = value
|
||||||
else
|
else
|
||||||
error("Unknown textSize unit: " .. unit)
|
ErrorHandler.error("Element", "Unknown textSize unit: " .. unit)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Validate pixel textSize value
|
-- Validate pixel textSize value
|
||||||
if props.textSize <= 0 then
|
if props.textSize <= 0 then
|
||||||
error("textSize must be greater than 0, got: " .. tostring(props.textSize))
|
ErrorHandler.error("Element", "textSize must be greater than 0, got: " .. tostring(props.textSize))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Pixel textSize value
|
-- Pixel textSize value
|
||||||
@@ -925,6 +995,7 @@ function Element.new(props)
|
|||||||
|
|
||||||
-- Track if positioning was explicitly set
|
-- Track if positioning was explicitly set
|
||||||
if props.positioning then
|
if props.positioning then
|
||||||
|
validateEnum(props.positioning, Positioning, "positioning")
|
||||||
self.positioning = props.positioning
|
self.positioning = props.positioning
|
||||||
self._originalPositioning = props.positioning
|
self._originalPositioning = props.positioning
|
||||||
self._explicitlyAbsolute = (props.positioning == Positioning.ABSOLUTE)
|
self._explicitlyAbsolute = (props.positioning == Positioning.ABSOLUTE)
|
||||||
@@ -1119,6 +1190,26 @@ function Element.new(props)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.positioning == Positioning.FLEX then
|
if self.positioning == Positioning.FLEX then
|
||||||
|
-- Validate enum properties
|
||||||
|
if props.flexDirection then
|
||||||
|
validateEnum(props.flexDirection, FlexDirection, "flexDirection")
|
||||||
|
end
|
||||||
|
if props.flexWrap then
|
||||||
|
validateEnum(props.flexWrap, FlexWrap, "flexWrap")
|
||||||
|
end
|
||||||
|
if props.justifyContent then
|
||||||
|
validateEnum(props.justifyContent, JustifyContent, "justifyContent")
|
||||||
|
end
|
||||||
|
if props.alignItems then
|
||||||
|
validateEnum(props.alignItems, AlignItems, "alignItems")
|
||||||
|
end
|
||||||
|
if props.alignContent then
|
||||||
|
validateEnum(props.alignContent, AlignContent, "alignContent")
|
||||||
|
end
|
||||||
|
if props.justifySelf then
|
||||||
|
validateEnum(props.justifySelf, JustifySelf, "justifySelf")
|
||||||
|
end
|
||||||
|
|
||||||
self.flexDirection = props.flexDirection or FlexDirection.HORIZONTAL
|
self.flexDirection = props.flexDirection or FlexDirection.HORIZONTAL
|
||||||
self.flexWrap = props.flexWrap or FlexWrap.NOWRAP
|
self.flexWrap = props.flexWrap or FlexWrap.NOWRAP
|
||||||
self.justifyContent = props.justifyContent or JustifyContent.FLEX_START
|
self.justifyContent = props.justifyContent or JustifyContent.FLEX_START
|
||||||
|
|||||||
Reference in New Issue
Block a user