Error handling in lua learning

Keywords: Programming socket

error handling

dynamic link

  1. In Lua, dynamic links are considered the parent of all other mechanisms

  2. So you can use it to dynamically load any other mechanism not in Lua

  3. Two parameters required for package.loadlib

    1. Full path to the library
    2. Correct function name
  4. The loadlib function loads the specified library and links it into Lua

  5. It does not call any functions in the library

  6. Instead, a function written in C is returned as a Lua function

  7. If an error occurs while loading the library or looking for the initialization function, nil and an error message are returned

local path = "c:/lua/5.1/socket.so"
local f = package.loadlib(path, "luaopen_socket")
  1. Usually use require to load the C library. This function will search the specified library
  2. Then load the library with loadlib and return the initialization function
  3. This initialization function should register the functions provided in the library with Lua, just like other functions defined in the Lua code block

error

  1. Lua is an extension language, usually embedded in applications

  2. If we crash or exit directly when an error occurs, we can't capture where the error occurred

  3. So whenever Lua has an error, it should end the current block and return to the application

  4. Any unexpected condition in Lua causes an error, such as:

    1. Add two non numeric values
    2. Call on a value that is not a function
    3. Index a value that is not a Table
  5. You can explicitly raise an error by calling the error function

    1. Function that needs to pass in an error message
do
    print("enter a number:")
    n = io.read("*number")
    if not n then 
        error("invalid input")
    end
end
 
-- Equivalent to the above code
do
	print("enter a number:")
	n = assert(io.read("*number"), "invalid input")
end
  1. assert returns the first parameter if it is true
  2. If the first parameter is false or nil, an error will be raised
  3. The second parameter is an optional information string
  4. Its parameters are evaluated when assert is called
  5. In the following code, Lua will connect strings even if n is a numeric type
n = io.read()
assert(tonumber(n), "invalid input:" .. n .. " is not a number")
  1. When a function encounters an unexpected situation, i.e. "exception", two basic behaviors can be taken

    1. Return error code (usually nil)
    2. Raise an error (call error)
  2. sin passes in table as a parameter

-- Return an error code, check sin Function return value
local res = math.sin(x)
if not res then
	<Error handling code>
end

-- call sin Before, check the parameters
if not tonumber(x) then
   	<Error handling code> 
end
  1. Usually neither the parameters nor the return value of sin are checked

  2. You can stop the calculation and give an error message

  3. Non existence of io.open file or abnormal behavior when access is denied

  4. Whether a file exists or not can be verified by whether it can be opened

  5. When io.open is unable to open a file, nil should be returned with an error message attached

do
    local file, msg
    repeat
        print("enter a file name:")
        local name = io.read()
        if not name then
            return
        end
        -- io.open The first parameter is the file path, and the second parameter is the open mode, r Is character mode
        -- io.open If it succeeds, the file handle will be returned. If it cannot be opened, the file handle will be returned nil And error messages
        file, msg = io.open(name, "r")
        if not file then
            print(msg)
        end
	until file
end

-- Equivalent to the above code.On error message io.open The second return value of, and becomes the assert Second parameter of
do
    local file, msg
    repeat
        print("enter a file name:")
        local name = io.read()
        if not name then
            return
        end
       file = assert(io.open(name, "r"))
	until file
end

Error handling and exceptions

  1. In most cases, you don't need to do any error handling in Lua, which is the responsibility of the application calling Lua

  2. Because all Lua activities start with a single call from the application

    1. Lua is usually required to execute a block
    2. If an error occurs, the call returns the error code and is processed by the application
  3. When an error occurs in the interpreter program, the main loop prints the error message, then continues to display the prompt and waits for subsequent commands to be executed

  4. When handling errors in Lua, pcall must be used to wrap the code to be executed. P > means protect

  5. pcall can catch any errors raised when a function executes

    1. If there are no errors, it will return true and the return value of the function call
    2. If there is an error, it will return false and error message
-- Execute a paragraph Lua Code,To capture all errors in execution, you need to encapsulate this code into a function
function foo()
    <code block>
    if Unexpected conditions then 
        error()
    end
    <code block>
    print(a[i]) -- Potential errors, a Maybe not one table
    <code block>
end

if pcall(foo) then
    -- implement foo No error occurred at
    <Regular code>
else
    -- foo An error was raised for error handling
    <Error handling code>
end
  1. An anonymous function can be passed in when pcall is called

  2. The error message can be any value and is passed to the error function, which becomes the return value of pcall

if pcall (function ()
	-- <Protected code>        
    return 20 + 10 -- Code for testing "a" + 10
end) then
    -- <Regular code>
    print("ok")
else
    -- <Error handling code>
    print("error")
end

do
	local status, err = pcall(function ()
        error({code = 121})
 	end)
    print(status, err.code)
end
  1. A complete exception handling process in Lua is usually:
    1. Use error to throw an exception
    2. Use pcall to catch exceptions
    3. Error messages are used to identify the type or content of the error

Error messages and traceability

  1. An error message is usually a string that describes what went wrong
  2. Lua encounters an internal error, such as indexing a non table value, and an error message will be generated
  3. In other cases, the error message is the value passed to the error function
  4. As long as the error message is a string, Lua appends some information about where the error occurred
do
    local status, err = pcall(function () a ="a"+1 end)
    print(err)
end

do
    local status, err = pcall(function () 
            error("my 	error") 
    end)
    print(err)
end
-- Location information contains file name stdin And line number 3
-- stdin:3: my error
  1. The second parameter of the error function, level, indicates which function in the call level should report the current error, that is, who is responsible for the error
-- In a function, check at the beginning whether the passed in parameter is correct
do
    function foo(str)
        if type(str) ~= "string" then
            -- If the second parameter is not added, it is considered to be an error in reading the function and an error is reported, stdin:3: string expected
            -- error("string expected")
            -- With the second parameter, an error is considered at the call level and reported, stdin:9: string expected
            error("string expected", 2)
        end
        print(str)
    end

    foo({x = 1})
end

  1. When the pcall function returns an error message, it has destroyed part of the call stack

  2. If you want to get a complete trace back to the function call when the error occurs, rather than just get the location where the error occurred, you need to use the xpcall function

  3. The xpcall function takes two arguments

    1. Function to be called
    2. And an error handling function
  4. When an error occurs, Lua will call the error handling function before the call stack is expanded, and you can use the debug library to get the wrong additional information.

Two general processing functions of debug library

  1. debug.debug, which provides a Lua prompt for the user to check the cause of the error
  2. debug.traceback, build an extended error message based on the call stack
  3. The interpreter uses debug.traceback to build its error messages
  4. Any time you call debug.traceback, you can get the currently executed call stack
do
    local t = {2, 4, 6, 8 ,10}
    for i,v in ipairs(t) do
       	print(i, v)
        print(debug.traceback())
    end
end

This article is published by one article multiple platform ArtiPub Automatic publishing

Posted by mchip on Thu, 12 Mar 2020 21:54:50 -0700