diff --git a/WeakAuras/AuraEnvironment.lua b/WeakAuras/AuraEnvironment.lua index 61353a3..9ad5831 100644 --- a/WeakAuras/AuraEnvironment.lua +++ b/WeakAuras/AuraEnvironment.lua @@ -214,7 +214,10 @@ function WeakAuras.ActivateAuraEnvironment(id, cloneId, state, states, onlyConfi if(actions and actions.do_custom and actions.custom) then local func = WeakAuras.customActionsFunctions[id]["init"] if func then - xpcall(func, geterrorhandler()) + local ok, ret = xpcall(func) + if not ok then + geterrorhandler()(ret) + end end end end diff --git a/WeakAuras/GenericTrigger.lua b/WeakAuras/GenericTrigger.lua index d795abf..af11ddc 100644 --- a/WeakAuras/GenericTrigger.lua +++ b/WeakAuras/GenericTrigger.lua @@ -339,8 +339,9 @@ local function RunOverlayFuncs(event, state) for i, overlayFunc in ipairs(event.overlayFuncs) do state.additionalProgress[i] = state.additionalProgress[i] or {}; local additionalProgress = state.additionalProgress[i]; - local a, b, c = overlayFunc(event.trigger, state); - if (not a) then + local ok, a, b, c = pcall(overlayFunc, event.trigger, state); + if (not ok) then + geterrorhandler()(a) additionalProgress.min = nil; additionalProgress.max = nil; additionalProgress.direction = nil; @@ -386,8 +387,13 @@ local function callFunctionForActivateEvent(func, trigger, fallback, errorHandle if not func then return fallback end - local value = func(trigger) - return value or fallback + local ok, value = pcall(func, trigger) + if not ok then + errorHandler(value) + return fallback + else + return value + end end function WeakAuras.ActivateEvent(id, triggernum, data, state, errorHandler) @@ -419,8 +425,13 @@ function WeakAuras.ActivateEvent(id, triggernum, data, state, errorHandler) state.inverse = nil; state.autoHide = autoHide; elseif (data.durationFunc) then - local arg1, arg2, arg3, inverse = data.durationFunc(data.trigger); - arg1 = type(arg1) == "number" and arg1 or 0; + local ok, arg1, arg2, arg3, inverse = pcall(data.durationFunc, data.trigger); + if not ok then + errorHandler(arg1); + arg1 = 0; + arg2 = 0; + end + arg1 = type(arg1) == "number" and arg2 or 0; arg2 = type(arg2) == "number" and arg2 or 0; if (state.inverse ~= inverse) then @@ -525,13 +536,17 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 if(data.triggerFunc) then local untriggerCheck = false; if (data.statesParameter == "full") then - local returnValue = data.triggerFunc(allStates, event, arg1, arg2, ...); - if (returnValue) then + local ok, returnValue = pcall(data.triggerFunc, allStates, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif ok and returnValue then updateTriggerState = true; end elseif (data.statesParameter == "all") then - local returnValue = data.triggerFunc(allStates, event, arg1, arg2, ...); - if( (returnValue) or optionsEvent) then + local ok, returnValue = pcall(data.triggerFunc, allStates, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif (ok and returnValue) or optionsEvent then for id, state in pairs(allStates) do if (state.changed) then if (WeakAuras.ActivateEvent(id, triggernum, data, state, errorHandler)) then @@ -554,8 +569,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 end allStates[cloneId] = allStates[cloneId] or {}; local state = allStates[cloneId]; - local returnValue = data.triggerFunc(state, event, unit, arg1, arg2, ...); - if returnValue or optionsEvent then + local ok, returnValue = pcall(data.triggerFunc, state, event, unit, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif (ok and returnValue) or optionsEvent then if(WeakAuras.ActivateEvent(id, triggernum, data, state, errorHandler)) then updateTriggerState = true; end @@ -566,8 +583,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 elseif (data.statesParameter == "one") then allStates[""] = allStates[""] or {}; local state = allStates[""]; - local returnValue = data.triggerFunc(state, event, arg1, arg2, ...); - if returnValue or optionsEvent then + local ok, returnValue = pcall(data.triggerFunc, state, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif (ok and returnValue) or optionsEvent then if(WeakAuras.ActivateEvent(id, triggernum, data, state, errorHandler)) then updateTriggerState = true; end @@ -575,8 +594,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 untriggerCheck = true; end else - local returnValue = data.triggerFunc(event, arg1, arg2, ...); - if returnValue or optionsEvent then + local ok, returnValue = pcall(data.triggerFunc, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif (ok and returnValue) or optionsEvent then allStates[""] = allStates[""] or {}; local state = allStates[""]; if(WeakAuras.ActivateEvent(id, triggernum, data, state, errorHandler)) then @@ -589,8 +610,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 if (untriggerCheck and not optionsEvent) then if (data.statesParameter == "all") then if data.untriggerFunc then - local returnValue = data.untriggerFunc(allStates, event, arg1, arg2, ...); - if returnValue then + local ok, returnValue = pcall(data.untriggerFunc, allStates, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif (ok and returnValue) or optionsEvent then for id, state in pairs(allStates) do if (state.changed) then if (WeakAuras.EndEvent(id, triggernum, nil, state)) then @@ -606,8 +629,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 local cloneId = WeakAuras.multiUnitUnits[data.trigger.unit] and arg1 or "" local state = allStates[cloneId] if state then - local returnValue = data.untriggerFunc(state, event, arg1, arg2, ...); - if returnValue then + local ok, returnValue = pcall(data.untriggerFunc, state, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif ok and returnValue then if (WeakAuras.EndEvent(id, triggernum, nil, state)) then updateTriggerState = true; end @@ -619,8 +644,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 allStates[""] = allStates[""] or {}; local state = allStates[""]; if data.untriggerFunc then - local returnValue = data.untriggerFunc(state, event, arg1, arg2, ...); - if returnValue then + local ok, returnValue = pcall(data.untriggerFunc, state, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif (ok and returnValue) then if (WeakAuras.EndEvent(id, triggernum, nil, state)) then updateTriggerState = true; end @@ -628,8 +655,10 @@ local function RunTriggerFunc(allStates, data, id, triggernum, event, arg1, arg2 end else if data.untriggerFunc then - local returnValue = data.untriggerFunc(event, arg1, arg2, ...); - if returnValue then + local ok, returnValue = pcall(data.untriggerFunc, event, arg1, arg2, ...); + if not ok then + errorHandler(returnValue) + elseif (ok and returnValue) then allStates[""] = allStates[""] or {}; local state = allStates[""]; if(WeakAuras.EndEvent(id, triggernum, nil, state)) then @@ -1026,7 +1055,7 @@ function GenericTrigger.LoadDisplays(toLoad, loadEvent, ...) end for event in pairs(eventsToRegister) do - frame:RegisterEvent(event) + pcall(frame.RegisterEvent, frame, event) genericTriggerRegisteredEvents[event] = true; end @@ -1037,7 +1066,7 @@ function GenericTrigger.LoadDisplays(toLoad, loadEvent, ...) frame.unitFrames[unit].unit = unit frame.unitFrames[unit]:SetScript("OnEvent", HandleUnitEvent); end - frame.unitFrames[unit]:RegisterEvent(event) + pcall(frame.unitFrames[unit].RegisterEvent, frame.unitFrames[unit], event, unit) genericTriggerRegisteredUnitEvents[unit] = genericTriggerRegisteredUnitEvents[unit] or {}; genericTriggerRegisteredUnitEvents[unit][event] = true; end @@ -3646,26 +3675,56 @@ function GenericTrigger.CreateFallbackState(data, triggernum, state) WeakAuras.ActivateAuraEnvironment(data.id, "", state); local firstTrigger = data.triggers[1].trigger if (event.nameFunc) then - local name = event.nameFunc(firstTrigger); - state.name = name or nil; + local success, res = pcall(event.nameFunc, firstTrigger); + if not success then + geterrorhandler()(res) + state.name = nil + else + state.name = res or nil + end end if (event.iconFunc) then - local icon = event.iconFunc(firstTrigger); - state.icon = icon or nil; + local success, res = pcall(event.iconFunc, firstTrigger); + if not success then + geterrorhandler()(res) + state.icon = nil + else + state.icon = res or nil + end end if (event.textureFunc ) then - local texture = event.textureFunc(firstTrigger); - state.texture = texture or nil; + local success, res = pcall(event.textureFunc, firstTrigger); + if not success then + geterrorhandler()(res) + state.texture = nil + else + state.texture = res or nil + end end if (event.stacksFunc) then - local stacks = event.stacksFunc(firstTrigger); - state.stacks = stacks or nil; + local success, res = pcall(event.stacksFunc, firstTrigger); + if not success then + geterrorhandler()(res) + state.stacks = nil + else + state.stacks = res or nil + end end if (event.durationFunc) then local arg1, arg2, arg3, inverse = event.durationFunc(firstTrigger); + local success, arg1, arg2, arg3, inverse = pcall(event.durationFunc, firstTrigger); + if not success then + geterrorhandler()(arg1) + state.progressType = "timed"; + state.duration = 0; + state.expirationTime = math.huge; + state.value = nil; + state.total = nil; + return; + end arg1 = type(arg1) == "number" and arg1 or 0; arg2 = type(arg2) == "number" and arg2 or 0; diff --git a/WeakAuras/RegionTypes/DynamicGroup.lua b/WeakAuras/RegionTypes/DynamicGroup.lua index 6c9cf58..4534e7b 100644 --- a/WeakAuras/RegionTypes/DynamicGroup.lua +++ b/WeakAuras/RegionTypes/DynamicGroup.lua @@ -310,9 +310,11 @@ local sorters = { local sortFunc = WeakAuras.LoadFunction("return " .. sortStr, data.id, "custom sort") or noop return function(a, b) WeakAuras.ActivateAuraEnvironment(data.id) - local result = sortFunc(a, b) + local ok, result = pcall(sortFunc, a, b) WeakAuras.ActivateAuraEnvironment() - if result then + if not ok then + geterrorhandler()(result) + else return result end end @@ -367,7 +369,10 @@ local anchorers = { local anchorFunc = WeakAuras.LoadFunction("return " .. anchorStr, data.id, "custom frame anchor") or noop return function(frames, activeRegions) WeakAuras.ActivateAuraEnvironment(data.id) - anchorFunc(frames, activeRegions) + local ok, ret = pcall(anchorFunc, frames, activeRegions) + if not ok then + geterrorhandler()(ret) + end WeakAuras.ActivateAuraEnvironment() end end @@ -715,11 +720,12 @@ local growers = { local growFunc = WeakAuras.LoadFunction("return " .. growStr, data.id, "custom grow") or noop return function(newPositions, activeRegions) WeakAuras.ActivateAuraEnvironment(data.id) - growFunc(newPositions, activeRegions) + local ok, ret = pcall(growFunc, newPositions, activeRegions) WeakAuras.ActivateAuraEnvironment() - --if not ok then - -- wipe(newPositions) - --end + if not ok then + geterrorhandler()(ret) + wipe(newPositions) + end end end } @@ -731,7 +737,10 @@ local function createGrowFunc(data) end local function SafeGetPos(region, func) - return func(region) + local ok, value1, value2 = pcall(func, region) + if ok then + return value1, value2 + end end local function modify(parent, region, data) diff --git a/WeakAuras/RegionTypes/RegionPrototype.lua b/WeakAuras/RegionTypes/RegionPrototype.lua index b4c277e..eb49626 100644 --- a/WeakAuras/RegionTypes/RegionPrototype.lua +++ b/WeakAuras/RegionTypes/RegionPrototype.lua @@ -283,7 +283,10 @@ end local function RunCode(self, func) if func and not WeakAuras.IsOptionsOpen() then WeakAuras.ActivateAuraEnvironment(self.id, self.cloneId, self.state, self.states); - xpcall(func, geterrorhandler()); + local ok, ret = pcall(func); + if not ok then + geterrorhandler()(ret) + end WeakAuras.ActivateAuraEnvironment(nil); end end @@ -304,7 +307,10 @@ local function UpdatePosition(self) local yOffset = self.yOffset + (self.yOffsetAnim or 0) + (self.yOffsetRelative or 0) self:RealClearAllPoints(); - self:SetPoint(self.anchorPoint, self.relativeTo, self.relativePoint, xOffset, yOffset); + local ok, ret = pcall(self.SetPoint, self, self.anchorPoint, self.relativeTo, self.relativePoint, xOffset, yOffset); + if not ok then + geterrorhandler()(ret) + end end local function ResetPosition(self) diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index 7d04991..5aee8b4 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -831,8 +831,12 @@ end local customConditionTestFunctions = {}; function WeakAuras.CallCustomConditionTest(testFunctionNumber, ...) - local result = customConditionTestFunctions[testFunctionNumber](...) - return result + local ok, result = pcall(customConditionTestFunctions[testFunctionNumber], ...) + if not ok then + geterrorhandler()(result) + elseif (ok) then + return result + end end local function CreateTestForCondition(input, allConditionsTemplate, usedStates) @@ -4276,8 +4280,12 @@ function WeakAuras.Add(data, takeSnapshot, simpleChange) if takeSnapshot then WeakAuras.SetMigrationSnapshot(data.uid, snapshot) end - WeakAuras.PreAdd(data) - pAdd(data, simpleChange) + local ok, ret = pcall(WeakAuras.PreAdd, data) + if not ok then + geterrorhandler()(ret) + elseif ok then + pAdd(data, simpleChange) + end end function WeakAuras.SetRegion(data, cloneId) @@ -4697,7 +4705,10 @@ function WeakAuras.PerformActions(data, when, region) local func = WeakAuras.customActionsFunctions[data.id][when] if func then WeakAuras.ActivateAuraEnvironment(region.id, region.cloneId, region.state, region.states); - xpcall(func, geterrorhandler()); + local ok, ret = pcall(func); + if not ok then + geterrorhandler()(ret) + end WeakAuras.ActivateAuraEnvironment(nil); end end @@ -4783,40 +4794,64 @@ function WeakAuras.UpdateAnimations() WeakAuras.ActivateAuraEnvironment(anim.name, anim.cloneId, anim.region.state, anim.region.states); if(anim.translateFunc) then if (anim.region.SetOffsetAnim) then - local x, y = anim.translateFunc(progress, 0, 0, anim.dX, anim.dY); - anim.region:SetOffsetAnim(x, y); + local ok, x, y = pcall(anim.translateFunc, progress, 0, 0, anim.dX, anim.dY); + if not ok then + errorHandler(x) + else + anim.region:SetOffsetAnim(x, y); + end else anim.region:ClearAllPoints(); - local x, y = anim.translateFunc(progress, anim.startX, anim.startY, anim.dX, anim.dY); - anim.region:SetPoint(anim.selfPoint, anim.anchor, anim.anchorPoint, x, y); + local ok, x, y = xpcall(anim.translateFunc, progress, anim.startX, anim.startY, anim.dX, anim.dY); + if not ok then + errorHandler(x) + else + anim.region:SetPoint(anim.selfPoint, anim.anchor, anim.anchorPoint, x, y); + end end end if(anim.alphaFunc) then - local alpha = anim.alphaFunc(progress, anim.startAlpha, anim.dAlpha); - if (anim.region.SetAnimAlpha) then - anim.region:SetAnimAlpha(alpha); + local ok, alpha = pcall(anim.alphaFunc, progress, anim.startAlpha, anim.dAlpha); + if not ok then + errorHandler(alpha) else - anim.region:SetAlpha(alpha); + if (anim.region.SetAnimAlpha) then + anim.region:SetAnimAlpha(alpha); + else + anim.region:SetAlpha(alpha); + end end end if(anim.scaleFunc) then - local scaleX, scaleY = anim.scaleFunc(progress, 1, 1, anim.scaleX, anim.scaleY); - if(anim.region.Scale) then - anim.region:Scale(scaleX, scaleY); + local ok, scaleX, scaleY = pcall(anim.scaleFunc, progress, 1, 1, anim.scaleX, anim.scaleY); + if (ok) then + errorHandler(scaleX) else - anim.region:SetWidth(anim.startWidth * scaleX); - anim.region:SetHeight(anim.startHeight * scaleY); + if(anim.region.Scale) then + anim.region:Scale(scaleX, scaleY); + else + anim.region:SetWidth(anim.startWidth * scaleX); + anim.region:SetHeight(anim.startHeight * scaleY); + end end end if(anim.rotateFunc and anim.region.Rotate) then - local rotate = anim.rotateFunc(progress, anim.startRotation, anim.rotate); - anim.region:Rotate(rotate); + local ok, rotate = pcall(anim.rotateFunc, progress, anim.startRotation, anim.rotate); + if not ok then + errorHandler(rotate) + else + anim.region:Rotate(rotate); + end end if(anim.colorFunc and anim.region.ColorAnim) then local startR, startG, startB, startA = anim.region:GetColor(); startR, startG, startB, startA = startR or 1, startG or 1, startB or 1, startA or 1; - local r, g, b, a = anim.colorFunc(progress, startR, startG, startB, startA, anim.colorR, anim.colorG, anim.colorB, anim.colorA); - anim.region:ColorAnim(r, g, b, a); + local ok, r, g, b, a = pcall(anim.colorFunc, progress, startR, startG, startB, startA, anim.colorR, anim.colorG, anim.colorB, anim.colorA); + if not ok then + errorHandler(r) + else + anim.region:ColorAnim(r, g, b, a); + end end WeakAuras.ActivateAuraEnvironment(nil); if(finished) then @@ -5855,7 +5890,12 @@ local function evaluateTriggerStateTriggers(id) result = true; else if (triggerState[id].disjunctive == "custom" and triggerState[id].triggerLogicFunc) then - result = triggerState[id].triggerLogicFunc(triggerState[id].triggers); + local ok + ok, result = pcall(triggerState[id].triggerLogicFunc, triggerState[id].triggers); + if not ok then + geterrorhandler()(result) + result = false + end end end @@ -6035,7 +6075,13 @@ function WeakAuras.RunCustomTextFunc(region, customFunc) end end - local custom = {customFunc(expirationTime or math.huge, duration or 0, progress, dur, name, icon, stacks)} + local custom = {pcall(customFunc, expirationTime or math.huge, duration or 0, progress, dur, name, icon, stacks)} + if not custom[1] then + geterrorhandler()(custom[2]) + else + table.remove(custom, 1) + end + WeakAuras.ActivateAuraEnvironment(nil) return custom end @@ -6560,11 +6606,13 @@ local function GetAnchorFrame(data, region, parent) WeakAuras.StartProfileSystem("custom region anchor") WeakAuras.StartProfileAura(region.id) WeakAuras.ActivateAuraEnvironment(region.id, region.cloneId, region.state) - local ok, frame = xpcall(region.customAnchorFunc, geterrorhandler()) + local ok, frame = pcall(region.customAnchorFunc) WeakAuras.ActivateAuraEnvironment() WeakAuras.StopProfileSystem("custom region anchor") WeakAuras.StopProfileAura(region.id) - if ok and frame then + if not ok then + geterrorhandler()(frame) + elseif ok and frame then return frame elseif WeakAuras.IsOptionsOpen() then return parent @@ -6591,7 +6639,13 @@ function WeakAuras.AnchorFrame(data, region, parent) if not anchorParent then return end if (data.anchorFrameParent or data.anchorFrameParent == nil or data.anchorFrameType == "SCREEN" or data.anchorFrameType == "MOUSE") then - region:SetParent(anchorParent); + local errorhandler = function(text) + geterrorhandler()(L["'ERROR: Anchoring %s': \n"]:format(data.id) .. text) + end + local ok, ret = pcall(region.SetParent, region, anchorParent); + if not ok then + errorhandler(ret) + end else region:SetParent(frame); end