Module:ErrorHandling: Difference between revisions

// via Wikitext Extension for VSCode
Tag: Reverted
// via Wikitext Extension for VSCode
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
-- Module:ErrorHandling
--[[
-- A centralized error handling system for templates that provides error tracking,
* Name: ErrorHandling
-- reporting, and graceful failure recovery. It formats errors as data attributes
* Author: Mark W. Datysgeld
-- for the debug monitor to display in the browser console.
* Description: Centralized error handling system for templates with error tracking, reporting, and graceful failure recovery
* Notes: Formats errors as data attributes for debug monitor display in browser console; creates error contexts; provides protected function execution; supports emergency fallback displays; completely deprecates mw.log usage
]]


local ErrorHandling = {}
local ErrorHandling = {}
-- Standard error messages for common scenarios
ErrorHandling.STANDARD_MESSAGES = {
    TEMPLATE_RENDER_ERROR = "<!-- Error rendering template -->",
    MODULE_LOAD_ERROR = "<!-- Error loading module -->",
    PROPERTY_ERROR = "<!-- Error processing semantic properties -->"
    -- Add more standard messages as needed
}


-- Creates a new error context for a template
-- Creates a new error context for a template
Line 14: Line 24:
         START_TIME = os.clock() * 1000,  -- Store in milliseconds
         START_TIME = os.clock() * 1000,  -- Store in milliseconds
         ERROR_COUNT = 0,
         ERROR_COUNT = 0,
        STATUS_COUNT = 0,
         ERRORS = {},
         ERRORS = {},
        STATUSES = {},
         HAS_CRITICAL_ERROR = false
         HAS_CRITICAL_ERROR = false
     }
     }
Line 45: Line 57:
      
      
     -- Return the error context for chaining
     -- Return the error context for chaining
    return context
end
-- Add a status message to the context
-- @param context The error context
-- @param source The source of the status message (function name)
-- @param message The status message
-- @param details Optional additional details
-- @return The context (for chaining)
function ErrorHandling.addStatus(context, source, message, details)
    -- Increment the status count
    context.STATUS_COUNT = (context.STATUS_COUNT or 0) + 1
   
    -- Add the status to the list
    table.insert(context.STATUSES, {
        id = context.STATUS_COUNT,
        source = source or "unknown",
        message = message or "Unknown status",
        details = details or ""
    })
   
    -- Return the context for chaining
     return context
     return context
end
end
Line 80: Line 114:
     -- Create hidden div with minimal footprint
     -- Create hidden div with minimal footprint
     return string.format('<div style="display:none"%s></div>', attrStr)
     return string.format('<div style="display:none"%s></div>', attrStr)
end
-- Format the status context for debugging output using data attributes
-- @param context The error context
-- @return HTML string with data attributes containing status information
function ErrorHandling.formatStatusOutput(context)
    -- If no statuses, return empty string
    if not context.STATUSES or #context.STATUSES == 0 then
        return ""
    end
   
    -- Build minimal data attribute div
    local divAttributes = {
        ['data-template-status'] = "1",
        ['data-status-count'] = tostring(#context.STATUSES)
    }
   
    -- Add individual status attributes with minimal naming
    for _, stat in ipairs(context.STATUSES) do
        divAttributes['data-status-' .. stat.id .. '-source'] = stat.source
        divAttributes['data-status-' .. stat.id .. '-msg'] = stat.message
        if stat.details and stat.details ~= "" then
            divAttributes['data-status-' .. stat.id .. '-details'] = stat.details
        end
    end
   
    -- Build attribute string efficiently
    local attrStr = ""
    for k, v in pairs(divAttributes) do
        attrStr = attrStr .. ' ' .. k .. '="' .. v .. '"'
    end
   
    -- Create hidden div with minimal footprint
    return string.format('<div style="display:none"%s></div>', attrStr)
end
-- Formats and combines both error and status outputs
-- @param context The context object
-- @return A string containing HTML for both errors and statuses
function ErrorHandling.formatCombinedOutput(context)
    local errorOutput = ErrorHandling.formatOutput(context)
    local statusOutput = ErrorHandling.formatStatusOutput(context)
   
    -- Simply concatenate the two outputs. If one is empty, it won't affect the other.
    -- A newline is added to ensure they are on separate lines in the HTML source.
    if errorOutput ~= "" and statusOutput ~= "" then
        return errorOutput .. "\n" .. statusOutput
    elseif errorOutput ~= "" then
        return errorOutput
    else
        return statusOutput
    end
end
end


Line 90: Line 176:
function ErrorHandling.createEmergencyDisplay(args, errorSource, errorMessage, templateType)
function ErrorHandling.createEmergencyDisplay(args, errorSource, errorMessage, templateType)
     -- Extract critical information for minimal display
     -- Extract critical information for minimal display
     local title = args.name or "Unnamed " .. (templateType or "Item")
     local title = args.name or ("Unnamed " .. (templateType or "Item"))
      
      
     -- Create minimal fallback with error data attributes
     -- Create minimal fallback with error data attributes
Line 130: Line 216:
end
end


-- Log field processing information for debugging
-- Get a standard error message with fallback
-- @param context The error context
-- @param messageKey The key of the standard message to retrieve
-- @param stage The processing stage (e.g., "getFieldValue", "processField")
-- @param defaultMessage Optional fallback message if the key is not found
-- @param fieldKey The field key being processed
-- @return The standard message or the default message
-- @param fieldValue The current value of the field
function ErrorHandling.getMessage(messageKey, defaultMessage)
-- @return The error context (for chaining)
     if ErrorHandling.STANDARD_MESSAGES and ErrorHandling.STANDARD_MESSAGES[messageKey] then
function ErrorHandling.logFieldProcessing(context, stage, fieldKey, fieldValue)
        return ErrorHandling.STANDARD_MESSAGES[messageKey]
     -- Create a unique ID for this log entry
     end
    local logId = "field_" .. context.ERROR_COUNT + 1
     return defaultMessage or "<!-- Error -->"
    context.ERROR_COUNT = context.ERROR_COUNT + 1
      
     -- Add the log entry with field processing details
    table.insert(context.ERRORS, {
        id = logId,
        source = "FieldProcessing",
        message = stage .. ": " .. (fieldKey or "unknown"),
        details = "Value: " .. (type(fieldValue) == "string" and fieldValue or type(fieldValue)),
        isCritical = false,
        isDebug = true  -- Mark as debug entry
    })
   
    return context
end
end