start testing
This commit is contained in:
445
modules/ErrorCodes.lua
Normal file
445
modules/ErrorCodes.lua
Normal file
@@ -0,0 +1,445 @@
|
||||
--- Error code definitions for FlexLove
|
||||
--- Provides centralized error codes, descriptions, and suggested fixes
|
||||
---@class ErrorCodes
|
||||
local ErrorCodes = {}
|
||||
|
||||
-- Error code categories
|
||||
ErrorCodes.categories = {
|
||||
VAL = "Validation",
|
||||
LAY = "Layout",
|
||||
REN = "Render",
|
||||
THM = "Theme",
|
||||
EVT = "Event",
|
||||
RES = "Resource",
|
||||
SYS = "System",
|
||||
}
|
||||
|
||||
-- Error code definitions
|
||||
ErrorCodes.codes = {
|
||||
-- Validation Errors (VAL_001 - VAL_099)
|
||||
VAL_001 = {
|
||||
code = "FLEXLOVE_VAL_001",
|
||||
category = "VAL",
|
||||
description = "Invalid property type",
|
||||
suggestion = "Check the property type matches the expected type (e.g., number, string, table)",
|
||||
},
|
||||
VAL_002 = {
|
||||
code = "FLEXLOVE_VAL_002",
|
||||
category = "VAL",
|
||||
description = "Property value out of range",
|
||||
suggestion = "Ensure the value is within the allowed min/max range",
|
||||
},
|
||||
VAL_003 = {
|
||||
code = "FLEXLOVE_VAL_003",
|
||||
category = "VAL",
|
||||
description = "Required property missing",
|
||||
suggestion = "Provide the required property in your element definition",
|
||||
},
|
||||
VAL_004 = {
|
||||
code = "FLEXLOVE_VAL_004",
|
||||
category = "VAL",
|
||||
description = "Invalid color format",
|
||||
suggestion = "Use valid color format: {r, g, b, a} with values 0-1, hex string, or Color object",
|
||||
},
|
||||
VAL_005 = {
|
||||
code = "FLEXLOVE_VAL_005",
|
||||
category = "VAL",
|
||||
description = "Invalid unit format",
|
||||
suggestion = "Use valid unit format: number (px), '50%', '10vw', '5vh', etc.",
|
||||
},
|
||||
VAL_006 = {
|
||||
code = "FLEXLOVE_VAL_006",
|
||||
category = "VAL",
|
||||
description = "Invalid file path",
|
||||
suggestion = "Check that the file path is correct and the file exists",
|
||||
},
|
||||
VAL_007 = {
|
||||
code = "FLEXLOVE_VAL_007",
|
||||
category = "VAL",
|
||||
description = "Invalid enum value",
|
||||
suggestion = "Use one of the allowed enum values for this property",
|
||||
},
|
||||
VAL_008 = {
|
||||
code = "FLEXLOVE_VAL_008",
|
||||
category = "VAL",
|
||||
description = "Invalid text input",
|
||||
suggestion = "Ensure text meets validation requirements (length, pattern, allowed characters)",
|
||||
},
|
||||
|
||||
-- Layout Errors (LAY_001 - LAY_099)
|
||||
LAY_001 = {
|
||||
code = "FLEXLOVE_LAY_001",
|
||||
category = "LAY",
|
||||
description = "Invalid flex direction",
|
||||
suggestion = "Use 'horizontal' or 'vertical' for flexDirection",
|
||||
},
|
||||
LAY_002 = {
|
||||
code = "FLEXLOVE_LAY_002",
|
||||
category = "LAY",
|
||||
description = "Circular dependency detected",
|
||||
suggestion = "Remove circular references in element hierarchy or layout constraints",
|
||||
},
|
||||
LAY_003 = {
|
||||
code = "FLEXLOVE_LAY_003",
|
||||
category = "LAY",
|
||||
description = "Invalid dimensions (negative or NaN)",
|
||||
suggestion = "Ensure width and height are positive numbers",
|
||||
},
|
||||
LAY_004 = {
|
||||
code = "FLEXLOVE_LAY_004",
|
||||
category = "LAY",
|
||||
description = "Layout calculation overflow",
|
||||
suggestion = "Reduce complexity of layout or increase recursion limit",
|
||||
},
|
||||
LAY_005 = {
|
||||
code = "FLEXLOVE_LAY_005",
|
||||
category = "LAY",
|
||||
description = "Invalid alignment value",
|
||||
suggestion = "Use valid alignment values (flex-start, center, flex-end, etc.)",
|
||||
},
|
||||
LAY_006 = {
|
||||
code = "FLEXLOVE_LAY_006",
|
||||
category = "LAY",
|
||||
description = "Invalid positioning mode",
|
||||
suggestion = "Use 'absolute', 'relative', 'flex', or 'grid' for positioning",
|
||||
},
|
||||
LAY_007 = {
|
||||
code = "FLEXLOVE_LAY_007",
|
||||
category = "LAY",
|
||||
description = "Grid layout error",
|
||||
suggestion = "Check grid template columns/rows and item placement",
|
||||
},
|
||||
|
||||
-- Rendering Errors (REN_001 - REN_099)
|
||||
REN_001 = {
|
||||
code = "FLEXLOVE_REN_001",
|
||||
category = "REN",
|
||||
description = "Invalid render state",
|
||||
suggestion = "Ensure element is properly initialized before rendering",
|
||||
},
|
||||
REN_002 = {
|
||||
code = "FLEXLOVE_REN_002",
|
||||
category = "REN",
|
||||
description = "Texture loading failed",
|
||||
suggestion = "Check image path and format, ensure file exists",
|
||||
},
|
||||
REN_003 = {
|
||||
code = "FLEXLOVE_REN_003",
|
||||
category = "REN",
|
||||
description = "Font loading failed",
|
||||
suggestion = "Check font path and format, ensure file exists",
|
||||
},
|
||||
REN_004 = {
|
||||
code = "FLEXLOVE_REN_004",
|
||||
category = "REN",
|
||||
description = "Invalid color value",
|
||||
suggestion = "Color components must be numbers between 0 and 1",
|
||||
},
|
||||
REN_005 = {
|
||||
code = "FLEXLOVE_REN_005",
|
||||
category = "REN",
|
||||
description = "Clipping stack overflow",
|
||||
suggestion = "Reduce nesting depth or check for missing scissor pops",
|
||||
},
|
||||
REN_006 = {
|
||||
code = "FLEXLOVE_REN_006",
|
||||
category = "REN",
|
||||
description = "Shader compilation failed",
|
||||
suggestion = "Check shader code for syntax errors",
|
||||
},
|
||||
REN_007 = {
|
||||
code = "FLEXLOVE_REN_007",
|
||||
category = "REN",
|
||||
description = "Invalid nine-patch configuration",
|
||||
suggestion = "Check nine-patch slice values and image dimensions",
|
||||
},
|
||||
|
||||
-- Theme Errors (THM_001 - THM_099)
|
||||
THM_001 = {
|
||||
code = "FLEXLOVE_THM_001",
|
||||
category = "THM",
|
||||
description = "Theme file not found",
|
||||
suggestion = "Check theme file path and ensure file exists",
|
||||
},
|
||||
THM_002 = {
|
||||
code = "FLEXLOVE_THM_002",
|
||||
category = "THM",
|
||||
description = "Invalid theme structure",
|
||||
suggestion = "Theme must return a table with 'name' and component styles",
|
||||
},
|
||||
THM_003 = {
|
||||
code = "FLEXLOVE_THM_003",
|
||||
category = "THM",
|
||||
description = "Required theme property missing",
|
||||
suggestion = "Ensure theme has required properties (name, base styles, etc.)",
|
||||
},
|
||||
THM_004 = {
|
||||
code = "FLEXLOVE_THM_004",
|
||||
category = "THM",
|
||||
description = "Invalid component style",
|
||||
suggestion = "Component styles must be tables with valid properties",
|
||||
},
|
||||
THM_005 = {
|
||||
code = "FLEXLOVE_THM_005",
|
||||
category = "THM",
|
||||
description = "Theme loading failed",
|
||||
suggestion = "Check theme file for Lua syntax errors",
|
||||
},
|
||||
THM_006 = {
|
||||
code = "FLEXLOVE_THM_006",
|
||||
category = "THM",
|
||||
description = "Invalid theme color",
|
||||
suggestion = "Theme colors must be valid color values (hex, rgba, Color object)",
|
||||
},
|
||||
|
||||
-- Event Errors (EVT_001 - EVT_099)
|
||||
EVT_001 = {
|
||||
code = "FLEXLOVE_EVT_001",
|
||||
category = "EVT",
|
||||
description = "Invalid event type",
|
||||
suggestion = "Use valid event types (mousepressed, textinput, etc.)",
|
||||
},
|
||||
EVT_002 = {
|
||||
code = "FLEXLOVE_EVT_002",
|
||||
category = "EVT",
|
||||
description = "Event handler error",
|
||||
suggestion = "Check event handler function for errors",
|
||||
},
|
||||
EVT_003 = {
|
||||
code = "FLEXLOVE_EVT_003",
|
||||
category = "EVT",
|
||||
description = "Event propagation error",
|
||||
suggestion = "Check event bubbling/capturing logic",
|
||||
},
|
||||
EVT_004 = {
|
||||
code = "FLEXLOVE_EVT_004",
|
||||
category = "EVT",
|
||||
description = "Invalid event target",
|
||||
suggestion = "Ensure event target element exists and is valid",
|
||||
},
|
||||
EVT_005 = {
|
||||
code = "FLEXLOVE_EVT_005",
|
||||
category = "EVT",
|
||||
description = "Event handler not a function",
|
||||
suggestion = "Event handlers must be functions",
|
||||
},
|
||||
|
||||
-- Resource Errors (RES_001 - RES_099)
|
||||
RES_001 = {
|
||||
code = "FLEXLOVE_RES_001",
|
||||
category = "RES",
|
||||
description = "File not found",
|
||||
suggestion = "Check file path and ensure file exists in the filesystem",
|
||||
},
|
||||
RES_002 = {
|
||||
code = "FLEXLOVE_RES_002",
|
||||
category = "RES",
|
||||
description = "Permission denied",
|
||||
suggestion = "Check file permissions and access rights",
|
||||
},
|
||||
RES_003 = {
|
||||
code = "FLEXLOVE_RES_003",
|
||||
category = "RES",
|
||||
description = "Invalid file format",
|
||||
suggestion = "Ensure file format is supported (png, jpg, ttf, etc.)",
|
||||
},
|
||||
RES_004 = {
|
||||
code = "FLEXLOVE_RES_004",
|
||||
category = "RES",
|
||||
description = "Resource loading failed",
|
||||
suggestion = "Check file integrity and format compatibility",
|
||||
},
|
||||
RES_005 = {
|
||||
code = "FLEXLOVE_RES_005",
|
||||
category = "RES",
|
||||
description = "Image cache error",
|
||||
suggestion = "Clear image cache or check memory availability",
|
||||
},
|
||||
|
||||
-- System Errors (SYS_001 - SYS_099)
|
||||
SYS_001 = {
|
||||
code = "FLEXLOVE_SYS_001",
|
||||
category = "SYS",
|
||||
description = "Memory allocation failed",
|
||||
suggestion = "Reduce memory usage or check available memory",
|
||||
},
|
||||
SYS_002 = {
|
||||
code = "FLEXLOVE_SYS_002",
|
||||
category = "SYS",
|
||||
description = "Stack overflow",
|
||||
suggestion = "Reduce recursion depth or check for infinite loops",
|
||||
},
|
||||
SYS_003 = {
|
||||
code = "FLEXLOVE_SYS_003",
|
||||
category = "SYS",
|
||||
description = "Invalid state",
|
||||
suggestion = "Check initialization order and state management",
|
||||
},
|
||||
SYS_004 = {
|
||||
code = "FLEXLOVE_SYS_004",
|
||||
category = "SYS",
|
||||
description = "Module initialization failed",
|
||||
suggestion = "Check module dependencies and initialization order",
|
||||
},
|
||||
}
|
||||
|
||||
--- Get error information by code
|
||||
--- @param code string Error code (e.g., "VAL_001" or "FLEXLOVE_VAL_001")
|
||||
--- @return table? errorInfo Error information or nil if not found
|
||||
function ErrorCodes.get(code)
|
||||
-- Handle both short and full format
|
||||
local shortCode = code:gsub("^FLEXLOVE_", "")
|
||||
return ErrorCodes.codes[shortCode]
|
||||
end
|
||||
|
||||
--- Get human-readable description for error code
|
||||
--- @param code string Error code
|
||||
--- @return string description Error description
|
||||
function ErrorCodes.describe(code)
|
||||
local info = ErrorCodes.get(code)
|
||||
if info then
|
||||
return info.description
|
||||
end
|
||||
return "Unknown error code: " .. code
|
||||
end
|
||||
|
||||
--- Get suggested fix for error code
|
||||
--- @param code string Error code
|
||||
--- @return string suggestion Suggested fix
|
||||
function ErrorCodes.getSuggestion(code)
|
||||
local info = ErrorCodes.get(code)
|
||||
if info then
|
||||
return info.suggestion
|
||||
end
|
||||
return "No suggestion available"
|
||||
end
|
||||
|
||||
--- Get category for error code
|
||||
--- @param code string Error code
|
||||
--- @return string category Error category name
|
||||
function ErrorCodes.getCategory(code)
|
||||
local info = ErrorCodes.get(code)
|
||||
if info then
|
||||
return ErrorCodes.categories[info.category] or info.category
|
||||
end
|
||||
return "Unknown"
|
||||
end
|
||||
|
||||
--- List all error codes in a category
|
||||
--- @param category string Category code (e.g., "VAL", "LAY")
|
||||
--- @return table codes List of error codes in category
|
||||
function ErrorCodes.listByCategory(category)
|
||||
local result = {}
|
||||
for code, info in pairs(ErrorCodes.codes) do
|
||||
if info.category == category then
|
||||
table.insert(result, {
|
||||
code = code,
|
||||
fullCode = info.code,
|
||||
description = info.description,
|
||||
suggestion = info.suggestion,
|
||||
})
|
||||
end
|
||||
end
|
||||
table.sort(result, function(a, b)
|
||||
return a.code < b.code
|
||||
end)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Search error codes by keyword
|
||||
--- @param keyword string Keyword to search for
|
||||
--- @return table codes Matching error codes
|
||||
function ErrorCodes.search(keyword)
|
||||
keyword = keyword:lower()
|
||||
local result = {}
|
||||
for code, info in pairs(ErrorCodes.codes) do
|
||||
local searchText = (code .. " " .. info.description .. " " .. info.suggestion):lower()
|
||||
if searchText:find(keyword, 1, true) then
|
||||
table.insert(result, {
|
||||
code = code,
|
||||
fullCode = info.code,
|
||||
description = info.description,
|
||||
suggestion = info.suggestion,
|
||||
category = ErrorCodes.categories[info.category],
|
||||
})
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--- Get all error codes
|
||||
--- @return table codes All error codes
|
||||
function ErrorCodes.listAll()
|
||||
local result = {}
|
||||
for code, info in pairs(ErrorCodes.codes) do
|
||||
table.insert(result, {
|
||||
code = code,
|
||||
fullCode = info.code,
|
||||
description = info.description,
|
||||
suggestion = info.suggestion,
|
||||
category = ErrorCodes.categories[info.category],
|
||||
})
|
||||
end
|
||||
table.sort(result, function(a, b)
|
||||
return a.code < b.code
|
||||
end)
|
||||
return result
|
||||
end
|
||||
|
||||
--- Format error message with code
|
||||
--- @param code string Error code
|
||||
--- @param message string Error message
|
||||
--- @return string formattedMessage Formatted error message with code
|
||||
function ErrorCodes.formatMessage(code, message)
|
||||
local info = ErrorCodes.get(code)
|
||||
if info then
|
||||
return string.format("[%s] %s", info.code, message)
|
||||
end
|
||||
return message
|
||||
end
|
||||
|
||||
--- Validate that all error codes are unique and properly formatted
|
||||
--- @return boolean, string? Returns true if valid, or false with error message
|
||||
function ErrorCodes.validate()
|
||||
local seen = {}
|
||||
local fullCodes = {}
|
||||
|
||||
for code, info in pairs(ErrorCodes.codes) do
|
||||
-- Check for duplicates
|
||||
if seen[code] then
|
||||
return false, "Duplicate error code: " .. code
|
||||
end
|
||||
seen[code] = true
|
||||
|
||||
if fullCodes[info.code] then
|
||||
return false, "Duplicate full error code: " .. info.code
|
||||
end
|
||||
fullCodes[info.code] = true
|
||||
|
||||
-- Check format
|
||||
if not code:match("^[A-Z]+_[0-9]+$") then
|
||||
return false, "Invalid code format: " .. code .. " (expected CATEGORY_NUMBER)"
|
||||
end
|
||||
|
||||
-- Check full code format
|
||||
local expectedFullCode = "FLEXLOVE_" .. code
|
||||
if info.code ~= expectedFullCode then
|
||||
return false, "Mismatched full code for " .. code .. ": expected " .. expectedFullCode .. ", got " .. info.code
|
||||
end
|
||||
|
||||
-- Check required fields
|
||||
if not info.description or info.description == "" then
|
||||
return false, "Missing description for " .. code
|
||||
end
|
||||
if not info.suggestion or info.suggestion == "" then
|
||||
return false, "Missing suggestion for " .. code
|
||||
end
|
||||
if not info.category or info.category == "" then
|
||||
return false, "Missing category for " .. code
|
||||
end
|
||||
end
|
||||
|
||||
return true, nil
|
||||
end
|
||||
|
||||
return ErrorCodes
|
||||
Reference in New Issue
Block a user