Module:ErrorHandling
Appearance
Documentation for this module may be created at Module:ErrorHandling/doc
-- Module:ErrorHandling
-- A centralized error handling system for templates that provides error tracking,
-- reporting, and graceful failure recovery. It formats errors as data attributes
-- for the debug monitor to display in the browser console.
local ErrorHandling = {}
-- Creates a new error context for a template
-- @param templateName The name of the template (for error reporting)
-- @return A new error context table
function ErrorHandling.createContext(templateName)
return {
TEMPLATE_NAME = templateName or "UnknownTemplate",
START_TIME = os.clock() * 1000, -- Store in milliseconds
ERROR_COUNT = 0,
ERRORS = {},
HAS_CRITICAL_ERROR = false
}
end
-- Add an error to the context
-- @param context The error context
-- @param source The source of the error (function name)
-- @param message The error message
-- @param details Optional additional details about the error
-- @param isCritical Whether this is a critical error (default: false)
-- @return The error context (for chaining)
function ErrorHandling.addError(context, source, message, details, isCritical)
-- Increment the error count
context.ERROR_COUNT = context.ERROR_COUNT + 1
-- Add the error to the list
table.insert(context.ERRORS, {
id = context.ERROR_COUNT,
source = source or "unknown",
message = message or "Unknown error",
details = details or "",
isCritical = isCritical or false
})
-- Update critical error flag if needed
if isCritical then
context.HAS_CRITICAL_ERROR = true
end
-- Return the error context for chaining
return context
end
-- Format the error context for debugging output using data attributes
-- @param context The error context
-- @return HTML string with data attributes containing error information
function ErrorHandling.formatOutput(context)
-- If no errors, return empty string
if context.ERROR_COUNT == 0 then
return ""
end
-- Build minimal data attribute div
local divAttributes = {
['data-template-error'] = "1",
['data-error-count'] = tostring(context.ERROR_COUNT)
}
-- Add individual error attributes with minimal naming
for _, err in ipairs(context.ERRORS) do
divAttributes['data-error-' .. err.id .. '-source'] = err.source
divAttributes['data-error-' .. err.id .. '-msg'] = err.message
if err.details and err.details ~= "" then
divAttributes['data-error-' .. err.id .. '-details'] = err.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
-- Create emergency display for catastrophic failures with minimal markup
-- @param args The template arguments
-- @param errorSource The source of the error
-- @param errorMessage The error message
-- @param templateType The type of template (e.g. "Event", "Person")
-- @return HTML string with a minimal template display and error data
function ErrorHandling.createEmergencyDisplay(args, errorSource, errorMessage, templateType)
-- Extract critical information for minimal display
local title = args.name or "Unnamed " .. (templateType or "Item")
-- Create minimal fallback with error data attributes
return string.format(
'{| class="template-table" cellpadding="2"\n' ..
'|-\n| class="template-title template-title-%s" | <span>%s</span>\n' ..
'|}\n' ..
'<div style="display:none" data-template-error="1" data-critical="1" ' ..
'data-error-1-source="%s" data-error-1-msg="%s"></div>',
string.lower(templateType or "generic"),
title,
errorSource,
errorMessage
)
end
-- Protect a function with pcall and error handling
-- @param context The error context
-- @param funcName Name of the function (for error reporting)
-- @param func The function to protect
-- @param fallback Value to return if the function fails
-- @param ... Arguments to pass to the function
-- @return The result of the function, or fallback value on error
function ErrorHandling.protect(context, funcName, func, fallback, ...)
local success, result = pcall(func, ...)
if not success then
ErrorHandling.addError(
context,
funcName,
"Function execution failed",
tostring(result),
false
)
return fallback
end
return result
end
-- Protected module loading
-- @param context The error context
-- @param moduleName Name of the module to load
-- @param isCritical Whether failure to load is critical (default: false)
-- @return The loaded module, or an empty table on failure
function ErrorHandling.safeRequire(context, moduleName, isCritical)
local success, module = pcall(require, moduleName)
if not success then
-- Record the error
ErrorHandling.addError(
context,
"ModuleLoading",
"Failed to load module",
moduleName,
isCritical or false
)
-- Return an empty table as fallback
return {}
end
return module
end
return ErrorHandling