hotfix: Resolved critical QuestieQuest runtime crash and hardened error handler
This commit is contained in:
+6
-2
@@ -1,10 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## v1.5.8 (2026-04-07)
|
||||
## v1.5.9 (2026-04-08)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **[Fix — QuestLink Crash]** Resolved a critical LUA error in `Link.lua`: `attempt to concatenate local 'coloredQuestName' (a nil value)`. This was caused by the `ChatFilter` misidentifying non-quest bracketed patterns (like Keystone links `[Name (ID)]`) as quests. Added a defensive nil guard in `GetQuestHyperLink` and hardened the `ChatFilter` to verify quest names exist before attempting string replacement.
|
||||
- **[Fix — QuestieQuest Crash]** Resolved a critical runtime crash occurring after killing certain NPCs (specifically Water Revenant 30877 in Wintergrasp).
|
||||
- **Harden Error Handling**: Replaced the fragile `print(debugstack())` in `ERR_FUNCTION` with a robust `Questie:Error` handler to prevent secondary crashes from masking real errors.
|
||||
- **Fix NPC Mapping**: Resolved a variable shadowing bug and fixed the mapping logic in `QuestieQuestPrivates:killcredit` to ensure NPC objective data is correctly populated during combat updates.
|
||||
|
||||
## v1.5.8 (2026-04-07)
|
||||
|
||||
|
||||
## Questie-X - Expanded Font Selection
|
||||
|
||||
@@ -62,8 +62,13 @@ local NewThread = ThreadLib.ThreadSimple
|
||||
local NOP_FUNCTION = function()
|
||||
end
|
||||
local ERR_FUNCTION = function(err)
|
||||
print(err)
|
||||
print(debugstack())
|
||||
Questie:Error("[QuestieQuest] " .. tostring(err))
|
||||
if debugstack then
|
||||
local stack = debugstack()
|
||||
if stack and type(stack) == "string" then
|
||||
Questie:Debug(Questie.DEBUG_CRITICAL, "Stack Trace:\n" .. stack:sub(1, 1000))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- forward declaration
|
||||
|
||||
@@ -73,7 +73,7 @@ killcredit = function(npcId, objective, objectiveData)
|
||||
local killCreditNpcId = objectiveData.IdList[npcIdIndex]
|
||||
if killCreditNpcId and killCreditNpcId > 0 then
|
||||
local monsterResult = monster(killCreditNpcId, objective)
|
||||
if monsterResult then
|
||||
if monsterResult and monsterResult[killCreditNpcId] then
|
||||
ret[killCreditNpcId] = monsterResult[killCreditNpcId]
|
||||
foundValid = true
|
||||
end
|
||||
@@ -96,7 +96,7 @@ killcredit = function(npcId, objective, objectiveData)
|
||||
for searchId, npcRecord in pairs(npcData) do
|
||||
if npcRecord and npcRecord[1] and string.lower(npcRecord[1]) == string.lower(targetName) then
|
||||
local monsterResult = monster(searchId, objective)
|
||||
if monsterResult then
|
||||
if monsterResult and monsterResult[searchId] then
|
||||
ret[searchId] = monsterResult[searchId]
|
||||
foundValid = true
|
||||
Questie:Debug(Questie.DEBUG_DEVELOP, "[killcredit] Found NPC by name fallback:", searchId, targetName)
|
||||
@@ -137,7 +137,7 @@ monster = function(npcId, objective)
|
||||
local enableWaypoints = enableSpawns and 2 ~= rank -- a rare mob spawn. todo: option for this
|
||||
|
||||
---@type SpawnListNPC
|
||||
local monster = {
|
||||
local monsterData = {
|
||||
Id = npcId,
|
||||
Name = name,
|
||||
Spawns = enableSpawns and spawns or {},
|
||||
@@ -150,7 +150,7 @@ monster = function(npcId, objective)
|
||||
}
|
||||
|
||||
return {
|
||||
[npcId] = monster
|
||||
[npcId] = monsterData
|
||||
}
|
||||
end
|
||||
|
||||
@@ -231,16 +231,16 @@ item = function(itemId, objective)
|
||||
if (not itemId) then
|
||||
Questie:Error(
|
||||
"Corrupted objective data handed to objectiveSpawnListCallTable['item']:",
|
||||
"'" .. objective.Description .. "' -",
|
||||
"'" .. (objective.Description or "Unknown") .. "' -",
|
||||
"Please report this error on Discord or GitHub."
|
||||
)
|
||||
return nil
|
||||
end
|
||||
|
||||
local ret = {}
|
||||
local item = QuestieDB:GetItem(itemId)
|
||||
if item and item.Sources and (not item.Hidden) then
|
||||
for _, source in pairs(item.Sources) do
|
||||
local itemData = QuestieDB:GetItem(itemId)
|
||||
if itemData and itemData.Sources and (not itemData.Hidden) then
|
||||
for _, source in pairs(itemData.Sources) do
|
||||
if _QuestieQuest.objectiveSpawnListCallTable[source.Type] and source.Type ~= "item" then -- anti-recursive-loop check, should never be possible but would be bad if it was
|
||||
local sourceList = _QuestieQuest.objectiveSpawnListCallTable[source.Type](source.Id, objective)
|
||||
if not sourceList then
|
||||
@@ -261,7 +261,7 @@ item = function(itemId, objective)
|
||||
Id = id,
|
||||
Name = sourceData.Name,
|
||||
Hostile = true,
|
||||
ItemId = item.Id,
|
||||
ItemId = itemData.Id,
|
||||
TooltipKey = sourceData.TooltipKey,
|
||||
Spawns = {},
|
||||
Waypoints = {},
|
||||
@@ -312,7 +312,7 @@ spell = function(spellId, objective, objectiveData)
|
||||
if (not spellId) then
|
||||
Questie:Error(
|
||||
"Corrupted objective data handed to objectiveSpawnListCallTable['spell']:",
|
||||
"'" .. objective.Description .. "' -",
|
||||
"'" .. (objective.Description or "Unknown") .. "' -",
|
||||
"Please report this error on Discord or GitHub."
|
||||
)
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user