Custom Errors in Lua

It’s possible to use custom types as errors by implementing an error method on them. Here’s an example that uses a custom type to explicitly represent an argument error.

-- A custom error type usually has the suffix "Error".
local ArgError = {}
ArgError.__index = ArgError

function ArgError.new(arg, message)
    return setmetatable({arg = arg, message = message}, ArgError)
end

-- Adding this `error` method makes `ArgError` behave like an error.
function ArgError:error()
    return string.format("%d - %s", self.arg, self.message)
end

local function f(arg)
    if arg == 42 then
        -- Return our custom error.
        return -1, ArgError.new(arg, "can't work with it")
    end
    return arg + 3, nil
end

-- `pcall` is used for error handling in Lua.
-- It's similar to try/catch in other languages.
local success, result = pcall(function()
    local value, err = f(42)
    if err then
        error(err)
    end
    return value
end)

if not success then
    if getmetatable(result) == ArgError then
        print(result.arg)
        print(result.message)
    else
        print("err doesn't match ArgError")
    end
end

In this Lua version:

  1. We define a custom ArgError type using a table and metatable.
  2. The error method is implemented to make ArgError behave like an error.
  3. The f function returns our custom error when the argument is 42.
  4. In the main part of the script, we use pcall for error handling, which is Lua’s equivalent to try/catch in other languages.
  5. If an error occurs, we check if it’s an instance of ArgError using getmetatable.

When you run this script, it will output:

42
can't work with it

This demonstrates how to create and use custom error types in Lua, allowing for more detailed error information to be passed around in your program.