<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.iccup.org/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AError%2FDisplay</id>
	<title>Модуль:Error/Display - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.iccup.org/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3AError%2FDisplay"/>
	<link rel="alternate" type="text/html" href="https://wiki.iccup.org/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Error/Display&amp;action=history"/>
	<updated>2026-06-02T05:25:28Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.iccup.org/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Error/Display&amp;diff=777&amp;oldid=prev</id>
		<title>DarkMuse: Новая страница: «local Array = require(&#039;Module:Array&#039;) local ErrorExt = require(&#039;Module:Error/Ext&#039;) local Json = require(&#039;Module:Json&#039;) local Page = require(&#039;Module:Page&#039;) local String = require(&#039;Module:StringUtils&#039;) local Table = require(&#039;Module:Table&#039;)  local ErrorDisplay = {types = {}, propTypes = {}}  local FILTERED_ERROR_STACK_ITEMS = { 	&#039;^Module:ResultOrError:%d+: in function &lt;Module:ResultOrError:%d+&gt;$&#039;, 	&#039;^%[C%]: in function \&#039;xpcall\&#039;$&#039;, 	&#039;^Module:ResultOrError:%d+:...»</title>
		<link rel="alternate" type="text/html" href="https://wiki.iccup.org/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:Error/Display&amp;diff=777&amp;oldid=prev"/>
		<updated>2024-09-24T18:13:06Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «local Array = require(&amp;#039;Module:Array&amp;#039;) local ErrorExt = require(&amp;#039;Module:Error/Ext&amp;#039;) local Json = require(&amp;#039;Module:Json&amp;#039;) local Page = require(&amp;#039;Module:Page&amp;#039;) local String = require(&amp;#039;Module:StringUtils&amp;#039;) local Table = require(&amp;#039;Module:Table&amp;#039;)  local ErrorDisplay = {types = {}, propTypes = {}}  local FILTERED_ERROR_STACK_ITEMS = { 	&amp;#039;^Module:ResultOrError:%d+: in function &amp;lt;Module:ResultOrError:%d+&amp;gt;$&amp;#039;, 	&amp;#039;^%[C%]: in function \&amp;#039;xpcall\&amp;#039;$&amp;#039;, 	&amp;#039;^Module:ResultOrError:%d+:...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local Array = require(&amp;#039;Module:Array&amp;#039;)&lt;br /&gt;
local ErrorExt = require(&amp;#039;Module:Error/Ext&amp;#039;)&lt;br /&gt;
local Json = require(&amp;#039;Module:Json&amp;#039;)&lt;br /&gt;
local Page = require(&amp;#039;Module:Page&amp;#039;)&lt;br /&gt;
local String = require(&amp;#039;Module:StringUtils&amp;#039;)&lt;br /&gt;
local Table = require(&amp;#039;Module:Table&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local ErrorDisplay = {types = {}, propTypes = {}}&lt;br /&gt;
&lt;br /&gt;
local FILTERED_ERROR_STACK_ITEMS = {&lt;br /&gt;
	&amp;#039;^Module:ResultOrError:%d+: in function &amp;lt;Module:ResultOrError:%d+&amp;gt;$&amp;#039;,&lt;br /&gt;
	&amp;#039;^%[C%]: in function \&amp;#039;xpcall\&amp;#039;$&amp;#039;,&lt;br /&gt;
	&amp;#039;^Module:ResultOrError:%d+: in function \&amp;#039;try\&amp;#039;$&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local INLINE_ERROR_MESSAGE =&lt;br /&gt;
	&amp;#039;Unexpected Error, report this in #bugs on our [https://discord.gg/iccup Discord]. ${errorMessage}&amp;#039;&lt;br /&gt;
&lt;br /&gt;
---@param props {limit: integer?, errors: Error[]}&lt;br /&gt;
---@return Html&lt;br /&gt;
function ErrorDisplay.ErrorList(props)&lt;br /&gt;
	local defaultLimit = 5&lt;br /&gt;
	local limit = props.limit or defaultLimit&lt;br /&gt;
&lt;br /&gt;
	local boxesNode = mw.html.create(&amp;#039;span&amp;#039;):addClass(&amp;#039;stashed-errors&amp;#039;)&lt;br /&gt;
	for index, error in ipairs(props.errors) do&lt;br /&gt;
		boxesNode:node(ErrorDisplay.ErrorBox(error))&lt;br /&gt;
&lt;br /&gt;
		if index == limit and limit &amp;lt; #props.errors then&lt;br /&gt;
			local overflowNode = ErrorDisplay.Box{&lt;br /&gt;
				text = (#props.errors - limit) .. &amp;#039; additional errors not shown&amp;#039;,&lt;br /&gt;
			}&lt;br /&gt;
			boxesNode:node(overflowNode)&lt;br /&gt;
			return boxesNode&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return boxesNode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---@param props {hasDetails: boolean?, loggedInOnly: boolean?, text: string}&lt;br /&gt;
---@return Html&lt;br /&gt;
function ErrorDisplay.Box(props)&lt;br /&gt;
	local div = mw.html.create(&amp;#039;div&amp;#039;):addClass(&amp;#039;navigation-not-searchable ambox-wrapper&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;ambox wiki-bordercolor-dark wiki-backgroundcolor-light&amp;#039;)&lt;br /&gt;
		:addClass(props.loggedInOnly ~= false and &amp;#039;show-when-logged-in&amp;#039; or nil)&lt;br /&gt;
		:addClass(&amp;#039;ambox-red&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	local tbl = mw.html.create(&amp;#039;table&amp;#039;)&lt;br /&gt;
	local tr = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	tr:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;ambox-image&amp;#039;)&lt;br /&gt;
		:wikitext(&amp;#039;[[File:Emblem-important.svg|40px|link=]]&amp;#039;)&lt;br /&gt;
	tr:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;ambox-text&amp;#039;)&lt;br /&gt;
		:wikitext(props.text)&lt;br /&gt;
		:wikitext(props.hasDetails and &amp;#039; (stack trace logged)&amp;#039; or nil)&lt;br /&gt;
&lt;br /&gt;
	return div:node(tbl)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---@param error Error&lt;br /&gt;
---@return Html&lt;br /&gt;
function ErrorDisplay.ErrorBox(error)&lt;br /&gt;
	return ErrorDisplay.Box{&lt;br /&gt;
		hasDetails = error.stacks ~= nil,&lt;br /&gt;
		text = tostring(error),&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Shows the message and stack trace of a lua error. Suitable for use in a popup.&lt;br /&gt;
---@param error Error&lt;br /&gt;
---@return Html&lt;br /&gt;
function ErrorDisplay.ErrorDetails(error)&lt;br /&gt;
	local errorDetailsNode = mw.html.create(&amp;#039;div&amp;#039;):addClass(&amp;#039;error-details&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
	errorDetailsNode:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;error-details-text&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;error&amp;#039;)&lt;br /&gt;
		:css(&amp;#039;font-weight&amp;#039;, &amp;#039;bold&amp;#039;)&lt;br /&gt;
		:wikitext(error.header)&lt;br /&gt;
		:wikitext(error.message)&lt;br /&gt;
&lt;br /&gt;
	local stackTraceString = ErrorExt.makeFullStackTrace(error)&lt;br /&gt;
	if stackTraceString ~= &amp;#039;&amp;#039; then&lt;br /&gt;
		errorDetailsNode:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;error-details-stacks&amp;#039;)&lt;br /&gt;
			:wikitext(stackTraceString)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local extraPropsString = ErrorExt.printExtraProps(error)&lt;br /&gt;
	if extraPropsString then&lt;br /&gt;
		errorDetailsNode:tag(&amp;#039;div&amp;#039;):addClass(&amp;#039;error-details-additional-props&amp;#039;)&lt;br /&gt;
			:wikitext(extraPropsString)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return errorDetailsNode&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Simple error message when a short error message is needed&lt;br /&gt;
---Currently used for infobox errors&lt;br /&gt;
---@param error Error&lt;br /&gt;
---@return Html&lt;br /&gt;
function ErrorDisplay.InlineError(error)&lt;br /&gt;
	local errorText = String.interpolate(INLINE_ERROR_MESSAGE, {errorMessage = error.message})&lt;br /&gt;
	return mw.html.create(&amp;#039;span&amp;#039;):addClass(&amp;#039;error&amp;#039;):addClass(&amp;#039;show-when-logged-in&amp;#039;):wikitext(errorText)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---Builds a JSON string for use by `liquipedia.customLuaErrors` JS module with `error()`.&lt;br /&gt;
---@param error Error&lt;br /&gt;
---@return Html&lt;br /&gt;
function ErrorDisplay.ClassicError(error)&lt;br /&gt;
	local stackTrace = {}&lt;br /&gt;
&lt;br /&gt;
	local processStackFrame = function(frame, frameIndex)&lt;br /&gt;
		if frameIndex == 1 and frame == &amp;#039;[C]: ?&amp;#039; then&lt;br /&gt;
			return&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local stackEntry = {content = frame}&lt;br /&gt;
		local frameSplit = mw.text.split(frame, &amp;#039;:&amp;#039;, true)&lt;br /&gt;
		if (frameSplit[1] == &amp;#039;[C]&amp;#039; or frameSplit[1] == &amp;#039;(tail call)&amp;#039;) then&lt;br /&gt;
			stackEntry.prefix = frameSplit[1]&lt;br /&gt;
			stackEntry.content = mw.text.trim(table.concat(frameSplit, &amp;#039;:&amp;#039;, 2))&lt;br /&gt;
		elseif frameSplit[1]:sub(1, 3) == &amp;#039;mw.&amp;#039; then&lt;br /&gt;
			stackEntry.prefix = table.concat(frameSplit, &amp;#039;:&amp;#039;, 1, 2)&lt;br /&gt;
			stackEntry.content = table.concat(frameSplit, &amp;#039;:&amp;#039;, 3)&lt;br /&gt;
		elseif frameSplit[1] == &amp;#039;Module&amp;#039; then&lt;br /&gt;
			local wiki = not Page.exists(table.concat(frameSplit, &amp;#039;:&amp;#039;, 1, 2)) and &amp;#039;commons&amp;#039;&lt;br /&gt;
				or mw.text.split(mw.title.getCurrentTitle():canonicalUrl(), &amp;#039;/&amp;#039;, true)[4] or &amp;#039;commons&amp;#039;&lt;br /&gt;
			stackEntry.link = {wiki = wiki, title = table.concat(frameSplit, &amp;#039;:&amp;#039;, 1, 2), ln = frameSplit[3]}&lt;br /&gt;
			stackEntry.prefix = table.concat(frameSplit, &amp;#039;:&amp;#039;, 1, 3)&lt;br /&gt;
			stackEntry.content = table.concat(frameSplit, &amp;#039;:&amp;#039;, 4)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		table.insert(stackTrace, stackEntry)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	Array.forEach(error.stacks or {}, function(stack)&lt;br /&gt;
		local stackFrames = mw.text.split(stack, &amp;#039;\n&amp;#039;)&lt;br /&gt;
		stackFrames = Array.filter(&lt;br /&gt;
			Array.map(&lt;br /&gt;
				Array.sub(stackFrames, 2, #stackFrames),&lt;br /&gt;
				function(frame) return String.trim(frame) end&lt;br /&gt;
			),&lt;br /&gt;
			function(frame) return not Table.any(FILTERED_ERROR_STACK_ITEMS, function(_, filter)&lt;br /&gt;
				return string.find(frame, filter) ~= nil&lt;br /&gt;
			end) end&lt;br /&gt;
		)&lt;br /&gt;
		Array.forEach(stackFrames, processStackFrame)&lt;br /&gt;
	end)&lt;br /&gt;
&lt;br /&gt;
	local errorSplit = mw.text.split(error.message, &amp;#039;:&amp;#039;, true)&lt;br /&gt;
	local errorText&lt;br /&gt;
	if #errorSplit == 4 then&lt;br /&gt;
		errorText = string.format(&amp;#039;Lua error in %s:%s at line %s:%s.&amp;#039;, unpack(errorSplit))&lt;br /&gt;
	elseif #errorSplit &amp;gt; 4 then&lt;br /&gt;
		errorText = string.format(&amp;#039;Lua error in %s:%s at line %s:%s&amp;#039;, unpack(Array.sub(errorSplit, 1, 4)))&lt;br /&gt;
		errorText = errorText .. &amp;#039;:&amp;#039; .. table.concat(Array.sub(errorSplit, 5), &amp;#039;:&amp;#039;) .. &amp;#039;.&amp;#039;&lt;br /&gt;
	else&lt;br /&gt;
		errorText = string.format(&amp;#039;Lua error: %s.&amp;#039;, error.message)&lt;br /&gt;
	end&lt;br /&gt;
	local jsonData = Json.stringify({&lt;br /&gt;
		errorShort = errorText,&lt;br /&gt;
		stackTrace = stackTrace,&lt;br /&gt;
	}, {asArray = true})&lt;br /&gt;
	return mw.html.create(&amp;#039;div&amp;#039;)&lt;br /&gt;
				:tag(&amp;#039;strong&amp;#039;):addClass(&amp;#039;error&amp;#039;)&lt;br /&gt;
				:tag(&amp;#039;span&amp;#039;):addClass(&amp;#039;scribunto-error&amp;#039;)&lt;br /&gt;
				:wikitext(jsonData):wikitext(&amp;#039;.&amp;#039;)&lt;br /&gt;
				:allDone()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return ErrorDisplay&lt;/div&gt;</summary>
		<author><name>DarkMuse</name></author>
	</entry>
</feed>