Lua/Errors
Lua modules based on the Scribunto/Lua extension are stored in resource pages using the Module: namespace. Each module uses a table to hold functions and variables, and that containing table is returned at the end of the module code.[1] This lesson will show you how to troubleshoot script errors and handle run-time errors in your scripts.
Prerequisites
[edit | edit source]This lesson assumes you have already completed the Tables lesson.
Create a Lua Script with Errors and Error Handling
[edit | edit source]To create a Lua script with errors and error handling:
- Navigate to Module:Sandbox.
- Clear all existing code.
- It's a sandbox. Everyone is free to play in the sandbox. But if you find another user is actively editing the sandbox at the same time, you may also use Module:Sandbox/Username, where Username is your Wikiversity username.
- Add the following code and save the page:
local p = {} local function reciprocal1(value) return 1 / value end function p.test1(frame) local value = frame.args[1] return reciprocal1(value) end local function reciprocal2(value) if value == nil then error('value must exist') end if tonumber(value) == nil then error('value must be a number') end if tonumber(value) == 0 then error('value must not be 0') end return 1 / value end function p.test2(frame) local value = frame.args[1] return reciprocal2(value) end local function reciprocal3(value) assert(value, 'value must exist') assert(tonumber(value), 'value must be a number') assert(tonumber(value) ~= 0, 'value must not be zero') return 1 / value end function p.test3(frame) local value = frame.args[1] return reciprocal3(value) end function p.test4(frame) local value = frame.args[1] if pcall(function () result = reciprocal3(value) end) then return result else return 'Error: Value must exist, must be numeric, and not zero.' end end return p
Test Your Lua Script
[edit | edit source]To test your Lua script:
- Navigate to either the Module_talk:Sandbox page, the Wikiversity:Sandbox page, or your own user or sandbox page.
- Add the following code and save the page:
;Reciprocal 1 :{{#invoke:Sandbox|test1}} :{{#invoke:Sandbox|test1|x}} :{{#invoke:Sandbox|test1|0}} :{{#invoke:Sandbox|test1|2}} ;Reciprocal 2 :{{#invoke:Sandbox|test2}} :{{#invoke:Sandbox|test2|x}} :{{#invoke:Sandbox|test2|0}} :{{#invoke:Sandbox|test2|2}} ;Reciprocal 3 :{{#invoke:Sandbox|test3}} :{{#invoke:Sandbox|test3|x}} :{{#invoke:Sandbox|test3|0}} :{{#invoke:Sandbox|test3|2}} ;Reciprocal 4 :{{#invoke:Sandbox|test4}} :{{#invoke:Sandbox|test4|x}} :{{#invoke:Sandbox|test4|0}} :{{#invoke:Sandbox|test4|2}}
The result should be similar to:
- Reciprocal 1
- Script error
- Script error
- inf
- 0.5
- Reciprocal 2
- Script error
- Script error
- Script error
- 0.5
- Reciprocal 3
- Script error
- Script error
- Script error
- 0.5
- Reciprocal 4
- Error: Value must exist, must be numeric, and not zero.
- Error: Value must exist, must be numeric, and not zero.
- Error: Value must exist, must be numeric, and not zero.
- 0.5
Understand Your Lua Script
[edit | edit source]To understand your Lua script reciprocal1
function:
local function reciprocal1(value)
declares a local function namedreciprocal1
that accepts a single parametervalue
, which is the value whose reciprocal will be returned.return 1 / value
returns the reciprocal of value.end
ends the function.
To understand your Lua script test1
function:
function p.test1(frame)
declares a function namedtest1
that accepts a single parameterframe
, which is the object used to access parameters passed from #invoke.local value = frame.args[1]
defines a local variable namedvalue
and assigns the value of the first frame argument (parameter) passed with #invoke.return reciprocal1(value)
calls thereciprocal1
function, passing the variablevalue
and returns the result.end
ends the function.
To understand your Lua script reciprocal2
function:
local function reciprocal2(value)
declares a local function namedreciprocal2
that accepts a single parametervalue
, which is the value whose reciprocal will be returned.if value == nil then
creates a conditional code block and tests to see ifvalue
isnil
. If it is, an error is generated.error('value must exist')
generates an error with the given literal string as the error statement. Usingerror()
allows the script writer to determine the text of the error message that is returned to the calling function or wiki page that invoked the function.- When an error is generated, execution immediately returns to the calling function. Any additional code in the same function that comes after the error is not processed.
if tonumber(value) == nil
creates a conditional code block and tests to see ifvalue
is numeric. If it is not,tonumber
returnsnil
and an error is generated.if tonumber(value) == 0
creates a conditional code block and tests to see ifvalue
is0
. If it is, an error is generated.return 1 / value
returns the reciprocal of value.end
ends the function.
To understand your Lua script test2
function:
function p.test2(frame)
and the following code declares a function namedtest2
that accepts a single parameterframe
, which is the object used to access parameters passed from #invoke.local value = frame.args[1]
defines a local variable namedvalue
and assigns the value of the first frame argument (parameter) passed with #invoke.return reciprocal2(value)
calls thereciprocal2
function, passing the variablevalue
and returns the result.end
ends the function.
To understand your Lua script reciprocal3
function:
local function reciprocal3(value)
declares a local function namedreciprocal3
that accepts a single parametervalue
, which is the value whose reciprocal will be returned.assert(value, 'value must exist')
creates a self-contained conditional code block and tests to see ifvalue
isnil
If it is, an error is generated.- It is best practice to use
assert
to document and test any assumptions that are made regarding passed parameters.
- It is best practice to use
assert(tonumber(value), 'value must be a number')
creates a self-contained conditional code block and tests to see ifvalue
is numeric. If it is not,tonumber
returnsnil
and an error is generated.assert(tonumber(value) ~= 0, 'value must not be zero')
creates a conditional code block and tests to see ifvalue
is0
. If it is, an error is generated.return 1 / value
returns the reciprocal of value.end
ends the function.
To understand your Lua script test3
function:
function p.test3(frame)
and the following code declares a function namedtest3
that accepts a single parameterframe
, which is the object used to access parameters passed from #invoke.local value = frame.args[1]
defines a local variable namedvalue
and assigns the value of the first frame argument (parameter) passed with #invoke.return reciprocal3(value)
calls thereciprocal3
function, passing the variablevalue
and returns the result.end
ends the function.
To understand your Lua script test4
function:
function p.test4(frame)
and the following code declares a function namedtest4
that accepts a single parameterframe
, which is the object used to access parameters passed from #invoke.local value = frame.args[1]
defines a local variable namedvalue
and assigns the value of the first frame argument (parameter) passed with #invoke.if pcall(function () result = reciprocal3(value) end) then
creates a conditional code block that calls thereciprocal3
function, passingvalue
and storing the result. If no error occurs,result
is returned. If an error occurs, a literal string is returned instead.pcall()
uses the pcall (protected call) function to call a function and catch any errors that occur.function () ... end
creates a self-contained anonymous function that executes the code in ... as a function call.- The anonymous function is necessary to save the result of the
reciprocal3
function while also usingpcall()
to catch any errors that occur.
- The anonymous function is necessary to save the result of the
end
ends the function.
Conclusion
[edit | edit source]Congratulations! You've now created, tested, and understood a Lua script with error handling. Continue on to the Math Library lesson or return to the main Lua page to learn about other Lua code libraries.