Search code examples
error-handlingluacustom-error-handling

Handling Lua errors in a clean and effective manner


I'm currently trying to code an add-on the popular game World Of Warcraft for a friend. I don't understand too much about the game myself and debugging it within the game is difficult as he's having to do all the testing.

I'm pretty new to Lua, so this may be a very easy question to answer. But when a Lua error occurs in WoW it throws it on screen and gets in the way, this is very bad to a game player as it will stop their gameplay if it throws the exception at the wrong time. I'm looking for a way to cleanly handle the error being thrown. Here's my code so far for the function.

function GuildShoppingList:gslSlashProc()
    -- Actions to be taken when command /gsl is procced.
    BankTab = GetCurrentGuildBankTab()
    BankInfo = GetGuildBankText(BankTab)
    local Tabname, Tabicon, TabisViewable, TabcanDeposit, TabnumWithdrawals, remainingWithdrawals = GetGuildBankTabInfo(BankTab)
    p1 = BankInfo:match('%-%- GSL %-%-%s+(.*)%s+%-%- ENDGSL %-%-')
    if p1 == nil then
        self:Print("GSL could not retrieve information, please open the guild bank and select the info tab allow data collection to be made")
    else
        self:Print("Returning info for: "..Tabname)
        for id,qty in p1:gmatch('(%d+):(%d+)') do
            --do something with those keys:
            local sName, sLink, iRarity, iLevel, iMinLevel, sType, sSubType, iStackCount = GetItemInfo(id);
            local iSum = qty/iStackCount
            self:Print("We need "..sLink.." x"..qty.."("..iSum.." stacks of "..iStackCount..")")
        end
    end
end

The problem being when checking to see if p1 is nil, it still throws a Lua error about trying to call p1 as nil. It will be nil at times and this needs to be handled correctly.

What would be the correct most efficient way to go about this?


Solution

  • You might want to wrap your function in a pcall or xpcall which enables you to intercept any error thrown by Lua.

    Aside of that, I personally find this construct easier to read:

    p1=string.match(str,pat)
    if p1 then
        -- p1 is valid, eg not nil or false
    else
        -- handle the problems
    end