Astral Keys

Astral Keys

13M Downloads

Communications.lua:82: attempt to call field 'method' (a nil value)

WiNiFiX opened this issue ยท 17 comments

commented

Message: Interface\AddOns\AstralKeys\Communications.lua:82: attempt to call field 'method' (a nil value)
Time: Fri Jan 22 19:11:38 2021
Count: 4
Stack: Interface\AddOns\AstralKeys\Communications.lua:82: attempt to call field 'method' (a nil value)
[string "=[C]"]: in function `method'
[string "@interface\AddOns\AstralKeys\Communications.lua"]:82: in function <Interface\AddOns\AstralKeys\Communications.lua:70>

Locals:

commented

Getting spammed with a similar message when a certain guild member is online, the error always includes his character name and never happens when he is offline or with someone else's name. It started after I updated to 3.37. Initially he was on 3.36 but it persisted after he updated.

AstralKeys\Communications.lua:82: attempt to call field 'method' (a nil value)
[string "@AstralKeys\Communications.lua"]:82: in function <AstralKeys\Communications.lua:70>

Locals:
self = AstralComs {
 0 = <userdata>
 loadDelay = 3
 Init = <function> defined @AstralKeys\Communications.lua:175
 IsPrefixRegistered = <function> defined @AstralKeys\Communications.lua:59
 UnregisterPrefix = <function> defined @AstralKeys\Communications.lua:48
 OnEvent = <function> defined @AstralKeys\Communications.lua:70
 RegisterPrefix = <function> defined @AstralKeys\Communications.lua:34
 versionPrint = false
 delay = 0
 NewMessage = <function> defined @AstralKeys\Communications.lua:104
 queue = <table> {
 }
 SendMessage = <function> defined @AstralKeys\Communications.lua:134
 OnUpdate = <function> defined @AstralKeys\Communications.lua:150
 dtbl = <table> {
 }
}
event = "CHAT_MSG_ADDON"
prefix = "AstralKeys"
msg = "request"
channel = "GUILD"
sender = "Malutawien-Silvermoon"
objs = <table> {
 1 = <table> {
 }
 2 = <table> {
 }
 3 = <table> {
 }
 4 = <table> {
 }
 5 = <table> {
 }
 6 = <table> {
 }
}
arg = "request"
content = ""
(for generator) = <function> defined =[C]:-1
(for state) = <table> {
 1 = <table> {
 }
 2 = <table> {
 }
 3 = <table> {
 }
 4 = <table> {
 }
 5 = <table> {
 }
 6 = <table> {
 }
}
(for control) = 6
_ = 6
obj = <table> {
 prefix = "request"
}
(*temporary) = nil
(*temporary) = ""
(*temporary) = "Malutawien-Silvermoon"
(*temporary) = "request"
(*temporary) = "attempt to call field 'method' (a nil value)"
commented

It is likely caused by these lines here:

-- Let's just disable sending information if we are doing a boss fight
-- but keep updating individual keys if we receive them
-- keep the addon channel overhead low
AstralEvents:Register('ENCOUNTER_START', function()
AstralComs:UnregisterPrefix('GUILD', 'request')
end, 'encStart')
AstralEvents:Register('ENCOUNTER_END', function()
AstralComs:RegisterPrefix('GUILD', 'request', PushKeyList)
end, 'encStop')

PushKeyList is not defined in Communications.lua, it is defined in Lists/Guild.lua.

commented

I had this issue and attempted a quick solve by adding the middle line of the following after line 81 in Communications.lua:

if obj.prefix == arg then
if not obj.method then return end
obj.method(content, sender, msg)

I'm guessing this occurs as a symptom of another bug that's causing invalid messages to be sent by some users in some cases, but this appears (so-far) to stop the error from occurring on my client when that happens.

commented

it's almost certainly caused by this fix cccc879

  AstralEvents:Register('ENCOUNTER_END', function()
-	AstralComs:RegisterPrefix('GUID', 'request', PushKeyList)
+	AstralComs:RegisterPrefix('GUILD', 'request', PushKeyList)
  end, 'encStop')

which highlighted the bug shown by @GigaPatches - prior to this guild sharing was broken

commented

There are a couple of options here then.

it's almost certainly caused by this fix cccc879

  AstralEvents:Register('ENCOUNTER_END', function()
-	AstralComs:RegisterPrefix('GUID', 'request', PushKeyList)
+	AstralComs:RegisterPrefix('GUILD', 'request', PushKeyList)
  end, 'encStop')

which highlighted the bug shown by @GigaPatches - prior to this guild sharing was broken

Just because it's not registered in Communications.lua doesn't mean it won't work. The .toc has this class registered so it should still be able to work.

commented

I had this issue and attempted a quick solve by adding the middle line of the following after line 81 in Communications.lua:

if obj.prefix == arg then
if not obj.method then return end
obj.method(content, sender, msg)

I'm guessing this occurs as a symptom of another bug that's causing invalid messages to be sent by some users in some cases, but this appears (so-far) to stop the error from occurring on my client when that happens.

This is probably the best spot-fix until we can determine why guild messages are causing the issue. The ENCOUNTER_END should only be happening in dungeons but some of the reports from players are when other guild members log in.

commented

Just because it's not registered in Communications.lua doesn't mean it won't work. The .toc has this class registered so it should still be able to work.

Yes, it does. PushKeyList is a local function within Lists/Guild.lua, which means that it will not be available to Communications.lua as local indicates a lexical scope (i.e, the binding only exists within the code unit it is defined). After ENCOUNTER_END happens, WoW will execute code equivalent to the following:

AstralComs:RegisterPrefix('GUILD', 'request', nil)
-- nil, because PushKeyList is not within scope at the time of this call.

WoW does not share local scope among all files declared within .toc; you have to use a global (so that is placed on _G) to share values across scope. This is why all SavedVariables must be global too.

The ENCOUNTER_END should only be happening in dungeons but some of the reports from players are when other guild members log in.

If a Alice completes an encounter and a Bob, who is a member of Alice's guild, logs in, Alice will receive a 'request' message from Bob. If Alice has completed an encounter after logging in, but before Bob logs on, due to the aforementioned bug, her callback handler will be nil for the request message. That is why this error occurs when guild members log in.

The simplest fix would be to change PushKeyList to be global, rather than local.

This bug only occurs when:

  1. Alice has completed at least one encounter since logging in, which sets the guild request handler to nil.
  2. Bob triggers the CHALLENGE_MODE_MAPS_UPDATE event and is in Alice's guild. Bob will send a 'request' message to the guild, which Alice receives. Kaboom.
commented

Instead of writing to _G which seems to be slow wouldn't it be better to make the Guild.lua methods that are needed into a module that can be accessed?

commented

It seems like the function AstralComs:RegisterPrefix attempts to coalesce these calls into one table but may be working incorrectly?

commented

Instead of writing to _G which seems to be slow

Premature optimization is the root of all evil. Try it; if it has a meaningful impact on performance, then remove it. However, you'd only be writing to _G once - when the AddOn is loaded. If it were performance-impacting, I think it would be very negligible because of this.

that are needed into a module that can be accessed?

Unless Ace provides something, there's no way to use Lua modules (like require) in WoW's UI. All of the Ace libraries that approximate this stuff also use stuff on _G.

I don't really see any reason why _G would be meaningfully slower here. It is accepted practice.

It seems like the function AstralComs:RegisterPrefix attempts to coalesce these calls into one table but may be working incorrectly?

RegisterPrefix is working fine, the problem is that PushKeyList is nil within Communications.lua. If you fix that, everything else will work.

commented

Sorry, still getting my feet wet with LUA and didn't realize WoWUI didn't support modules.

commented

There's no need to apologize for learning :)

commented

So it would appear that removing the local completely then makes the function global by default and accessible?

commented

That's correct. The only issue you'll encounter here is that all names on _G must be globally unique - it'd be good practice to prefix it with something unique to your AddOn, like

function AstralKeys_PushKeyList()
  ...
end
commented

Ahh yeah that makes sense because if there's another global function called PushKeyList in another addon it won't be able to reference a particular function and probably bail out.

commented

I believe this fixes it here

#9

commented

Looks good to me!