Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Runtime Error caused by Widget.lua
Started by troylyndon May 22 2018 02:06 PM

15 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

troylyndon

[GLOBAL: userInfoPane.html]
troylyndon
  • Contributor

  • 483 posts
  • Corona SDK

Runtime Error
/Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widget-Library/widget.lua:27: attempt to index field '?' (a nile value)
 
This is the bug that has existed in my game for over a year. It doesn't happen often, but considering that the very line number of the issue is listed in our Testing log, should be enough of a reason for CoronaLabs to fix it once and for all. NOTE: It would be fine if the widget simply exited from the routine under this condition - as players could then still play our game without it crashing.

Here are more details about how and what is happening to cause widget to crash. Please be advised that this bug in widget is very difficult to duplicate. And these details now represent details that, under the same conditions, will crash for other developers, too. The challenge is in fully understanding how widget interacts with our own code (and time-based listeners) and display groups.

05-20 19:44:17.021 25811-27891/? I/Corona: ERROR: Runtime error
05-20 19:44:17.021 25811-27891/? I/Corona: /Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget.lua:27: attempt to index field '?' (a nil value)
                                           stack traceback:
                                               [C]: ?
                                               /Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget.lua:27: in function 'removeWidgets'
                                               /Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget.lua:32: in function 'removeWidgets'
                                               /Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget.lua:44: in function 'method'
                                               /Users/jenkins/slaveroot/workspace/Templates/label/android/platform/resources/init.lua:522: in function 'remove'
                                               ?: in function 'displayRemove'
                                               ?: in function 'cleanUpGameObjects'
                                               ?: in function '?'
                                               ?: in function 'listener'
                                               /Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/timer/timer.lua:210: in function 'method'
                                               /Users/jenkins/slaveroot/workspace/Templates/label/android/platform/resources/init.lua:221: in function </Users/jenkins/slaveroot/workspace/Templates/label/android/platform/resources/init.lua:190>

NOTE: I've reviewed my code where this happens and I found that, long ago, I attempted to prevent this from happening by checking if the scrollView object exists and if it does, simply send it to the scrollView:toBack without removing the group it is contained within. Also, when you see that the routine displayRemove is listed above, is this an error in widget or is it my own fw.displayRemove designed and implemented throughout the game to gracefully remove objects? Here is my own fw.displayRemove routine:
 
function fw.displayRemove(objOrGroup)
if objOrGroup and type(objOrGroup)=="table" then
   transition.cancel(objOrGroup)
   display.remove(objOrGroup)
   objOrGroup=nil
end
 
The only thing I can imagine that is happening is that calling my own routine to do this will remove the object or group "defined", but because the variable containing the object is simply passed into this function, the original variable still contains a reference to the object that no longer exists. Nevertheless, shouldn't widget know when its objects have been removed and stop attempting to operate?

I also notice that my listener, which is called 30 frames-per-second, is the routine that kicks this off from my function 'cleanUpGameObjects'. Is it possible that my function 'listener', which calls cleanUpGameObjects, is interrupting code that is running within widget, so that when widget begins running again, it has no reason to consider its own object has been removed in the middle of running? I'm grasping to consider every possibility.
 



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 24,308 posts
  • Corona Staff

Thanks for creating this thread. I didn't want to hijack the other thread.

 

It very well could be some form of race condition. I'm not sure why you're trying to call your listener 30 times per second, but it's possible that you could be trying to delete something that's in the process of being deleted, in particular if it's behind a timer that needs to remove something after a function is done with it.

 

Engineering took a look at this today. Let's see if they can find anything.

 

One last note, you keep talking about Enterprise/Native being needed to use your own copy of the widget library. This is not correct. The widgets are just lua code. You download the repo, drop it in your project folder along side main.lua, make a couple of changes to load the local copy and not the built-in version and you can use this from the simulator and with simulator builds. There is no need to venture into native development.

 

This is one reason why we open-sourced this library. We knew that people would want to make changes that would be unique to their app (now fixing bugs, admittedly that is something we should do). We want this to be available to everyone.

 

Rob



[TOPIC: post.html]
#3

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,486 posts
  • Corona SDK

You can download the Widgets library from Github and fix this issue yourself with a few nil checks. Not ideal but it's the only way to fix it in the short term.

Corona seem to be more interested in HTML5 builds four years too late and which generate zero income for anybody, than making core libraries robust enough for production use.

https://github.com/coronalabs/framework-widget

[TOPIC: post.html]
#4

vlads

[GLOBAL: userInfoPane.html]
vlads
  • Contributor

  • 526 posts
  • Corona Staff

We're trying to update that repo. Process which was pushing internal repo to public one got broken.



[TOPIC: post.html]
#5

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,840 posts
  • Corona SDK

By far the most common widget error is

/Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget_tableview.lua:1266: attempt to index field 'parent' (a nil value)

stack traceback:
	at (Unknown Function) (/Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget_tableview.lua:1266)
	at (Unknown Function) ((tail call))
	at ? (?:0)
	at (Unknown Function) (?:0)

I get around 40 to 50 per day being logged to my servers.


  • roaminggamer likes this

[TOPIC: post.html]
#6

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 24,308 posts
  • Corona Staff

That error appears to be a case of trying to insert a row into a tableView that doesn't exist, or is in the process of being removed, i.e. the parent object is nil. 

 

Could this be happening?

 

Rob



[TOPIC: post.html]
#7

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,840 posts
  • Corona SDK

Hi Rob

 

I do check that the row is valid before attempting to access it so I am not too sure on that.  I do the followiing

local function onRowRender( event )
  local row = event.row
  if isDisplayObject(row) then
    <build the row now>
  end
end
 

The check funciton is

function isDisplayObject(obj)
  --check for a valid display object
  if obj ~= nil then
    if type( obj.removeSelf ) == "function" then
      return true
    else return false end
  else return false end
end

So I would hope that would be hardened enough?



[TOPIC: post.html]
#8

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 24,308 posts
  • Corona Staff

It's happening when you call tableView:insertRow() not during the row's rendering step.

 

Rob



[TOPIC: post.html]
#9

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,840 posts
  • Corona SDK

Ah I see... what is the best way to check that tableView:insertRow() is a valid operation?

 

I would imagine it is happening on slow internet connections as the data is being pulled from my MySQL servers.



[TOPIC: post.html]
#10

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 24,308 posts
  • Corona Staff

I think that's where we need to harden that API call, but you probably could test to see if the tableView exists before you try and call insertRow().

 

Rob



[TOPIC: post.html]
#11

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,840 posts
  • Corona SDK

That's the thing, I do check and it is valid. 

 

Otherwise it would raise an error... something like "attempt to index field 'insertRow' (a nil value)"

 

I'm sure others would appreciate some hardening on the API here as I am sure I'm not the only one filling content from an external source.



[TOPIC: post.html]
#12

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,486 posts
  • Corona SDK

That's what I was seeing, I tested everything in my own code to absolutely make sure it wasn't nil, that it was a display object, that insertRow existed, but still 1 in maybe 1000 times this runtime error would occur. It was almost as if the tableView was in an invalid state, halfway towards being deleted.

 

 

In the end I just had to download the Widget library and put extra nil checks all over the place, but especially where I had seen errors come through on the logs. 



[TOPIC: post.html]
#13

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 24,308 posts
  • Corona Staff

We think we fixed this tableView:insertRow() issue in daily build 2018.3301. Can you give it a try?

 

Rob



[TOPIC: post.html]
#14

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,840 posts
  • Corona SDK

@Rob wow that was fast!  I will try 3301 and see if that helps.

 

Really great turnaround on this one.... I'm impressed.



[TOPIC: post.html]
#15

troylyndon

[GLOBAL: userInfoPane.html]
troylyndon
  • Contributor

  • 483 posts
  • Corona SDK

@Rob, thank you - I’ll create the next update with this version!

[TOPIC: post.html]
#16

troylyndon

[GLOBAL: userInfoPane.html]
troylyndon
  • Contributor

  • 483 posts
  • Corona SDK

We haven't seen a widget.lua crash occur yet in our recent update. Crossing our fingers that it's fixed. :)




[topic_controls]
[/topic_controls]