Unable to access Project Library function through Extension Method

I have a popup calendar with this script that fires upon a property change:

Pop Up Calendar Prop Change Script

kpiFunctions.kpiRestCall.updateKPIsonDateSelect(event)

Here is the structure of Project Library
image

kpiRestCall Functions Code

def kpiRestCall(kpiComponent,date):
	try:
		kpiComponent.endpoint = system.net.httpGet("{}/{}".format(kpiComponent.baseUrl,date))
	except:
		message = "Error retrieving data for {}".format(kpiComponent.name)
		system.gui.errorBox(message, title)
		
def updateKPIsonDateSelect(event):
	if event.propertyName == 'formattedDate':
		print event.source.date
		restDate = system.date.format(event.source.date, "MM-dd-yy")
		kpiCompList = []
		for comp in event.source.parent.getComponents():
			try:
				print comp.name
				thisTemplatePath = comp.templatePath
				kpiCompList.append(comp)
			except:
				print "Component " + comp.name + " is not a template!"
		for k in kpiCompList:
			kpiRestCall(k, restDate)

And here is the error message output

14:20:51.514 [AWT-EventQueue-0] INFO designer.update-and-save - Save finished in 33ms.
14:20:57.722 [AWT-EventQueue-0] INFO designer.update-and-save - Save finished in 26ms.
14:21:36.097 [AWT-EventQueue-0] INFO designer.update-and-save - Save finished in 30ms.
Tue Aug 31 14:00:25 EDT 2021
Popup Calendar
Component Popup Calendar is not a template!
MoltenPulled
PotsCharged
PostMeltAttainment
CasterPlantAttainment
Rectangle
Component Rectangle is not a template!
Dashboard Label
Component Dashboard Label is not a template!
14:21:45.027 [AWT-EventQueue-0] ERROR com.inductiveautomation.ignition.client.util.gui.ErrorUtil - <HTML>Error executing script for event:&nbsp;<code><b>propertyChange</b></code><BR>on component:&nbsp;<code><b>Popup Calendar</b></code>.
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last):
  File "<event:propertyChange>", line 1, in <module>
  **File "<module:kpiFunctions.kpiRestCall>", line 22, in updateKPIsonDateSelect**
**  File "<module:kpiFunctions.kpiRestCall>", line 7, in kpiRestCall**
NameError: global name 'title' is not defined

	at org.python.core.Py.NameError(Py.java:261)
	at org.python.core.PyFrame.getglobal(PyFrame.java:265)
	at org.python.pycode._pyx65.kpiRestCall$1(<module:kpiFunctions.kpiRestCall>:7)
	at org.python.pycode._pyx65.call_function(<module:kpiFunctions.kpiRestCall>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:150)
	at org.python.core.PyFunction.__call__(PyFunction.java:426)
	at org.python.pycode._pyx65.updateKPIsonDateSelect$2(<module:kpiFunctions.kpiRestCall>:21)
	at org.python.pycode._pyx65.call_function(<module:kpiFunctions.kpiRestCall>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:134)
	at org.python.core.PyFunction.__call__(PyFunction.java:416)
	at org.python.pycode._pyx36.f$0(<event:propertyChange>:1)
	at org.python.pycode._pyx36.call_function(<event:propertyChange>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1687)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:796)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:206)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter$ActionRunner.run(ActionAdapter.java:314)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: org.python.core.PyException: NameError: global name 'title' is not defined
	... 33 common frames omitted

It seems like it’s failing when it hits the actual rest call request but I am uncertain why. This error message specifically seems to be referring to a scope issues?
NameError: global name ‘title’ is not defined

The issue is happening in this function, specifically in your bare except clause (which I must recommend again - only except against your expected errors).

def kpiRestCall(kpiComponent,date):
	try:
		kpiComponent.endpoint = system.net.httpGet("{}/{}".format(kpiComponent.baseUrl,date))
	except:
		message = "Error retrieving data for {}".format(kpiComponent.name)
		system.gui.errorBox(message, title)

Your system.gui.errorBox you are providing message, which you define right above, and you are providing title - but you have not defined title anywhere. Define title somewhere (presumably in your except block) and this will go away.

Side note - if I were you, I’d do some testing and see exactly what sort of errors you do get from system.net.httpGet, and only catch those, and let the others bubble up. Failing silently (especially unintendedly) makes debugging a massive headache. Throw a logger in there too to log any errors - users will click through popups without reading and they’ll just tell you it didn’t work. Logging will give you a paper trail.

This function references a variable title but doesn't define it anywhere.

edit: ooph, didn't see @bkarabinchak.psi's post for some reason.

Thank you. Yes at some point I need to put proper logging in. I am an intern and this is a research project so nothing is super critical at the moment.

Does the ‘global’ part of the error message indicate project level scripts?

@Kevin.Herron I appreciate your contribution none the less.

1 Like

Not necessarily. It just means that the interpreter couldn’t find any object named title. This is a NameError, telling that you have used a variable or function which hasn’t been defined.

In this case global means in any scope the script has access to.

1 Like