How could this generate an error?

We are getting some errors reported to us from a couple of different users.  The error is the same and the stack trace we have points to the following function: -

local \_clearListLabel = function(name) for i = 1, #\_listValues do if \_listValues[i].name == name then if \_listValues[i].lbValue ~= nil then \_listValues[i].lbValue:removeSelf() \_listValues[i].lbValue = nil break end end end end

The error being report is in the “attempt to call method ‘removeSelf’ (a nil value)” on the line: -

\_listValues[i].lbValue:removeSelf()

Does anyone know how this could happen and if there is any other way to avoid it?

We cannot recreate the error.  It is very infrequent.  We have maybe 2,000 users of this App and we get this error reported 1 or 2 times a week, however it is very puzzling.

My only thought was maybe this function is being called twice.  So we are somehow getting a clash…  But the calling code does not support this…

no offense intended, but many potential vulnerabilities in that code, here’s what i see on quick glance:

  1. you appear to be “wiping” a value from an indexed array, yet I see no attempt to clean the array itself (fe, table.remove), very likely you’ve got “old stuff” lingering it that array that you don’t expect to be there.  next pass through that array you may find an unexpected entry with an old invalid display object and attempt to process it, generating error. of if there’s code elsewhere that cleans that array (not shown here) then check that for problems.  either way, fix this issue first, will likely completely solve problem (of “remnant display objects”) at its source (else, keep reading…)

  2. use display.remove(lbValue) instead of lbValue:removeSelf() (eliminates need for 5 below)

  3. are you certain that “name” is unique?

3b) else, why the break? (ie, intended logic is unclear - either break not needed, or could be a return)

  1. are you certain that if “name” exists then “lbValue” must be a valid display object? (and not some other non-nil value?)

  2. if you must, also test for lbValue.removeSelf ~= nil before calling (you may have a “partially torn-down” display object remnant)

  3. in dev-mode, force the caller to call this function twice, intentionally, immediately… does it replicate issue?  (if so, is it in response to a “button”?  if so, look for “leaks” in button event handler, perhaps an unintentional multitouch or somesuch when fudge-fingered)

hth

Thanks Dave.

This structure is part of a larger set of functions that provide drop down list functionality within a business app.  This function is an internal function called to clear one value from one particular list.  The page could have multiple lists on the page.

I can only think that it must be being called twice somehow.

I have taken your advice and implemented step 5 - just in case somehow the display object is getting corrupted.

I used to use display.remove, but I found it a bit flakey in the past so I have moved to a manual process of removal.  It is probably OK now, but the early version of corona this function was defo a bit dodge…

Don’t forgot to remove the object from the table too.

table.remove(\_listValues,i ) 

Yvan

I’d suggest running through the loop in reverse order if you are going to be removing elements while in the loop:

for i = #\_listValues, 1, -1 do

Otherwise you’ll end up hitting nil table entries towards the end of the loop, where entries have shifted down to fill the gap that was left when an entry was removed.

I think the real title of this forum post should be:

“How could this  Code  generate an error”

no offense intended, but many potential vulnerabilities in that code, here’s what i see on quick glance:

  1. you appear to be “wiping” a value from an indexed array, yet I see no attempt to clean the array itself (fe, table.remove), very likely you’ve got “old stuff” lingering it that array that you don’t expect to be there.  next pass through that array you may find an unexpected entry with an old invalid display object and attempt to process it, generating error. of if there’s code elsewhere that cleans that array (not shown here) then check that for problems.  either way, fix this issue first, will likely completely solve problem (of “remnant display objects”) at its source (else, keep reading…)

  2. use display.remove(lbValue) instead of lbValue:removeSelf() (eliminates need for 5 below)

  3. are you certain that “name” is unique?

3b) else, why the break? (ie, intended logic is unclear - either break not needed, or could be a return)

  1. are you certain that if “name” exists then “lbValue” must be a valid display object? (and not some other non-nil value?)

  2. if you must, also test for lbValue.removeSelf ~= nil before calling (you may have a “partially torn-down” display object remnant)

  3. in dev-mode, force the caller to call this function twice, intentionally, immediately… does it replicate issue?  (if so, is it in response to a “button”?  if so, look for “leaks” in button event handler, perhaps an unintentional multitouch or somesuch when fudge-fingered)

hth

Thanks Dave.

This structure is part of a larger set of functions that provide drop down list functionality within a business app.  This function is an internal function called to clear one value from one particular list.  The page could have multiple lists on the page.

I can only think that it must be being called twice somehow.

I have taken your advice and implemented step 5 - just in case somehow the display object is getting corrupted.

I used to use display.remove, but I found it a bit flakey in the past so I have moved to a manual process of removal.  It is probably OK now, but the early version of corona this function was defo a bit dodge…

Don’t forgot to remove the object from the table too.

table.remove(\_listValues,i ) 

Yvan

I’d suggest running through the loop in reverse order if you are going to be removing elements while in the loop:

for i = #\_listValues, 1, -1 do

Otherwise you’ll end up hitting nil table entries towards the end of the loop, where entries have shifted down to fill the gap that was left when an entry was removed.

I think the real title of this forum post should be:

“How could this  Code  generate an error”