Maximum recursion depth exceeded (Java StackOverflowError)

I'm using version 18.1.18. I have a table on a view which calls the onEditCellCommit and onSelectionChange component events. I am running the exact same script on both. It works perfectly on onEditCellCommit, but I get "maximum recursion depth exceeded (Java StackOverflowError)" error on line 3 when called by onSelectionChange. Here is the script:

def runAction(self, event):
	try:
		v_row = event['row']
		v_col = event['column']
		v_val = event['value'] 
		v_id = self.props.data[v_row].ID

		Resource_Limits.setDB(v_row, v_col, v_val, v_id)
	   
		self.refreshBinding("props.data")
	
	except Exception as e:
		Log.set_error(str(e),  'Resource Limits Table onSelectionChange')

I'm not sure what would cause it to run perfectly on one event and error on another.

Because refreshing the table's data causes the selected data to be recomputed from the new table, causing onSelectionChange to happen again. Boom, infinite recursion.

Commenting out self.refreshBinding("props.data") yeilds the same result. In fact, if I comment out everything except my try and line 3 I get the same result:

def runAction(self, event):
	try:
		v_row = event['row']
		'''v_col = event['column']
		v_val = event['value'] 
		v_id = self.props.data[v_row].ID

		Resource_Limits.setDB(v_row, v_col, v_val, v_id)
	   
		#self.refreshBinding("props.data")'''
	
	except Exception as e:
		Log.set_error(str(e),  'Resource Limits Table onSelectionChange')

Just tested it; even getting rid of the exception handling does it. And commenting out line 3 moves the error to line 4: v_col = event['column']

Why are you using subscript notation with your event variable? You should be using the documented attributes event.selectedRow, event.selectedColumn, and/or event.data.

https://docs.inductiveautomation.com/display/DOC81/Perspective+-+Table+Scripting#PerspectiveTableScripting-onSelectionChange

That the misuse of subscript notation in this case produces infinite recursion is a bug worth reporting, though.

I don't understand how it's not doing anything besides throwing KeyError. I certainly can't get it to do anything as bad as a stackoverflow.

Because that's what ChatGPT told me to do. LOL Anyways, I can try those out.

Sigh. Just say no to ChatGPT.

2 Likes

I'm a special case, PGriffith, a special case. I saw this case where you said it was a bug, but I figured it was handled since it was so old Tag.configure max recursion depth exceeded The weird thing is it works fine in onEditCellCommit

I'm trying to get on the good side of our new electronic overlords.

Ok, using event.selectedRow, event.selectedColumn doesn't cause an error, but I don't see how to get what I changed the cell value to. The event.data is the data before the edit. It kinda makes sense because my selected cell is now a different cell. Is there a way for me to commit the edit when a user selects a different cell. Can I fire the onEditCellCommit somehow?

So the real problem we are trying to solve is that when an edit is made, and a different cell is clicked on without first pressing the enter key, the cell edit is lost.

I found another thread in the forum about this problem, and this solution seems viable:

Messing around with this problem, I don't see any way to gain this functionality from the selection change event that you were originally trying to use.

However, I was able to gain this functionality by adding a custom property to the table called editString. Then, using the onEditCellStart event, I could clear the value from the editString prop using self.props.editString = ''. I could then keep track of what was typed using the onKeyPress event and the following code:

key = event.key
startingString = self.props.editString
self.props.editString = startingString + key

To make the editString commit when another cell was selected, I ran the normal onEditCellCommit script from the onEditCellCancel event using the custom editString property for the value instead of the event's value.

Unfortunately, this approach only works if the entry is completely new because if a small edit is made to the existing text, all that gets saved when another cell is selected is the text typed during the small edit. Therefore, to ensure that the entire string doesn't get replaced by a partial entry, you would need to clear the text at the beginning of the edit. Sadly, the table doesn't have a clear text on entry option, so to get this functionality, you would have to render a view with a text field that is configured to do this.

...and if you're rendering a text field view in the column, you should probably just follow through with the change script message suggested in the previous post.