Module:UtilsError
Jump to navigation
Jump to search
A utility module for error-handling, mainly with respect to argument validation.
Unlike other utilities, this page should not be imported at the top of a module. Instead, import it only at the precise location where you use it. This is so that the module is only linked on pages that actually have errors (see Guidelines:Modules#Performance Optimization).
error
error(error, [warning])
Parameters
error
- Error message to display.
[warning]
If
true
, the error message will also be logged as a warning.If a string, that message will be logged as the warning - this can be used to provide additional error information to editors. The message will also appear when hovering over the error.
Returns
- An error message in wikitext, linking to the page which invoked the function. This page, which is usually a template, should have documentation on the error.
Examples
# | Input | Result |
---|---|---|
1 | error("I AM ERROR")
| Error: I AM ERROR |
2 | error("I AM ERROR 2", true)
| Error: I AM ERROR 2 |
3 | error(
"I AM ERROR",
'warning message with [[links]] and <code>markup</code> and "quotes"'
)
| Error: I AM ERROR |
warn
warn(msg, [options])
Parameters
msg
- Warning message to log above the edit preview area.
[options]
[traceBack=true]
- If true, prints a stack trace of all module frames. If the invoking frame is a template, the name of the template is appended to the stack trace.
[omitFrames=0]
- Number of additional frames to omit from the top of the stack trace.
[includeInstance=true]
- If true, the warning will specify which #invoke call caused the warning. Useful when a template is used multiple times per page. Only accurate for templates with only 1 #invoke function.
Returns
- Logs the above message, possibly with a stack trace. Preview this page for an example of output. The logged message is returned.
Examples
# | Input | Output | Result |
---|---|---|---|
4 | warn("I AM ERROR")
| "I AM ERROR"
| I AM ERROR |
5 | warn("I AM ERROR", { omitFrames = 2 })
| "I AM ERROR"
| I AM ERROR |
6 | warn("I AM ERROR", { traceBack = false })
| "I AM ERROR"
| I AM ERROR |
local p = {}
local h = {}
local VariablesLua = mw.ext.VariablesLua
function p.error(msg, warnMsg)
local errorMessage = msg and ("Error: "..msg) or "Error"
local page = mw.getCurrentFrame():getParent():getTitle()
local hoverText = page
if warnMsg then
if type(warnMsg) == "boolean" then
warnMsg = msg or "Error"
end
warnMsg = p.warn(warnMsg)
if warnMsg ~= msg and msg ~= nil then
hoverText = warnMsg
end
end
hoverText = string.gsub(hoverText, '"', """)
hoverText = string.gsub(hoverText, "]", "]")
local err = string.format('[[%s|<strong class="error" title="<nowiki>%s</nowiki>">%s</strong>]]', page, hoverText, errorMessage)
return mw.getCurrentFrame():preprocess(err)
end
function p.warn(msg, options)
local options = options or {}
local omitFrames = options.omitFrames or 0
local traceBack = options.traceBack
local includeInstance = options.includeInstance
omitFrames = omitFrames or 0
local parentFrame = mw.getCurrentFrame():getParent()
local templateTitle = parentFrame and parentFrame:getTitle()
if templateTitle and mw.title.new(templateTitle).nsText == "Template" then
local instanceCount = h.getInstanceCount(templateTitle)
if instanceCount and includeInstance ~= false then
msg = string.format("Misuse of [[%s]] at instance %s: %s", templateTitle, instanceCount, msg)
else
msg = string.format("Misuse of [[%s]]: %s", templateTitle, msg)
end
traceBack = false
end
if traceBack ~= false then
local trace = ""
local callStack = debug.traceback("", 2)
for line in string.gmatch(callStack, "\tModule:[^:]*:[^\n]*\n") do
if omitFrames ~= 0 then
omitFrames = omitFrames - 1
else
line = string.gsub(line, "\tModule:([^:]*):(.*)", '::<span class="hidden-link">[[Module:%1]]:%2</span>')
trace = trace .. line .. "\n"
end
end
mw.addWarning(msg.."\n\n"..trace)
else
mw.addWarning(msg)
-- We also log the message as mw.addWarning currently doesn't work if the editor has enabled the preference "Show previews without reloading the page".
-- Unfortunately neither mw.addWarning nor mw.log work with the visual editor (even in source mode).
-- An alternative would be to throw an actual script error as most wikis do.
-- However, full errors degrade the reader experience.
-- Many of our validation errors are not so critical that readers should know that they even exist.
mw.log(msg)
end
return msg
end
-- [[Module:UtilsArg]] defines an "instance count" page variable which tracks the number of times a template has been used on the page until now
function h.getInstanceCount(templateTitle)
local var = VariablesLua.var("instanceCounter"..templateTitle)
if var ~= "" then
return var
else
return nil
end
end
function p.Schemas()
return {
error = {
error = {
type = "string",
required = true,
desc = "Error message to display.",
},
warning = {
desc = "<p>If <code>true</code>, the error message will also be logged as a warning.</p><p>If a string, that message will be logged as the warning - this can be used to provide additional error information to editors. The message will also appear when hovering over the error.</p>",
oneOf = {
{
type = "string",
},
{
type = "boolean",
},
},
},
},
warn = {
msg = {
type = "string",
required = true,
desc = "Warning message to log above the edit preview area.",
},
options = {
type = "record",
properties = {
{
name = "traceBack",
type = "boolean",
default = true,
desc = "If true, prints a stack trace of all module frames. If the invoking frame is a template, the name of the template is appended to the stack trace.",
},
{
name = "omitFrames",
type = "number",
default = 0,
desc = "Number of additional frames to omit from the top of the stack trace."
},
{
name = "includeInstance",
type = "boolean",
default = true,
desc = "If true, the warning will specify which #invoke call caused the warning. Useful when a template is used multiple times per page. Only accurate for templates with only 1 #invoke function.",
},
}
}
}
}
end
function p.Documentation()
return {
error = {
params = {"error", "warning"},
returns = "An error message in wikitext, linking to the page which invoked the function. This page, which is usually a template, should have documentation on the error.",
cases = {
resultOnly = true,
{
args = {"I AM ERROR"},
},
{
args = {"I AM ERROR 2", true},
},
{
args = {"I AM ERROR", 'warning message with [[links]] and <code>markup</code> and "quotes"'},
},
}
},
warn = {
params = {"msg", "options"},
returns = "Logs the above message, possibly with a stack trace. Preview this page for an example of output. The logged message is returned.",
cases = {
{
args = {"I AM ERROR"},
},
{
args = {"I AM ERROR", { omitFrames = 2 }},
},
{
args = {"I AM ERROR", { traceBack = false }},
}
},
},
}
end
return p