readBlocking and timeout exception

Dear community,

I am not able to catch a timeout exception from system.tag.readBlocking.

My tag event script looks as follows:

from java.util.concurrent import TimeoutException
logger = system.util.getLogger("blnWriteBlockingTimeoutTest.TagChangeEvent")
	
try:
	result = system.tag.writeBlocking(
		["[GLT_PROD_INTERNAL]ENE/BETDRG00UG/BHKW/intSumPowerJZD"], [570], 100)
	
	logger.info("result=%s" % result)

except TimeoutException:
	logger.warn("TimeoutException for tag path=%s" % tagPath)
except Exception as e:
	logger.warn("Unexpected Error for tag path=%s; Exception=%s" % (tagPath, e))

In the gateway log I see the following exception:

INFO   | jvm 1    | 2020/09/22 10:30:41 | E [Scripting[system_util_tag]    ] [08:30:41]: Error during blocking write of tags through scripting.
INFO   | jvm 1    | 2020/09/22 10:30:41 | java.util.concurrent.TimeoutException: null
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.util.concurrent.CompletableFuture.timedGet(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.util.concurrent.CompletableFuture.get(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.gateway.script.GatewayTagUtilities.writeBlockingImpl(GatewayTagUtilities.java:234)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.writeBlocking(AbstractTagUtilities.java:397)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at jdk.internal.reflect.GeneratedMethodAccessor133.invoke(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.lang.reflect.Method.invoke(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:524)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyObject.__call__(PyObject.java:515)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyObject.__call__(PyObject.java:519)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.pycode._pyx1595.valueChanged$1(<tagevent:valueChanged>:14)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.pycode._pyx1595.call_function(<tagevent:valueChanged>)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyTableCode.call(PyTableCode.java:171)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyBaseCode.call(PyBaseCode.java:308)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyFunction.function___call__(PyFunction.java:471)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyFunction.__call__(PyFunction.java:466)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at org.python.core.PyFunction.__call__(PyFunction.java:461)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:822)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:806)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:687)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$FunctionInvokerImpl.run(TagScriptManagerImpl.java:527)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.gateway.tags.scripting.events.AbstractTagScript.invoke(AbstractTagScript.java:34)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$Task.invoke(TagScriptManagerImpl.java:476)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$TagScriptDispatcher.run(TagScriptManagerImpl.java:439)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$ThrowableCatchingRunnable.run(BasicExecutionEngine.java:518)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 |       at java.base/java.lang.Thread.run(Unknown Source)
INFO   | jvm 1    | 2020/09/22 10:30:41 | I [b.TagChangeEvent              ] [08:30:41]: result=[Error_Exception]

As you can see, the two defined exception handlers (TimeoutException, Exception) are not called. But Ignition raises still a java.util.concurrent.TimeoutException.

Does any body know how I can gracefully handle the timeout exception?

This might help:

If the error was a direct throw of that TimeoutException, your except clause would work. But it is being wrapped in some other throwable (the TimeoutException add as the cause). I recommend this structure for this case:

import java.lang.Throwable

def someFunction():
	try:
		system.tag.writeBlocking(.....)
	except java.lang.Throwable, t:
		# do something, including looking at t.cause
	except Exception, e:
		# do something with other python problems.
2 Likes

Thanks for the recommendations. I tried to catch the error with

except java.lang.Throwable, t:

but it did not work. I did not wrap it in a function but I think that’s not an issue.
If I put the same code in the Script Console the exception is caught even with java.util.concurrent.TimeoutException. Why does it not work inside the tag change event?

It is likely that it is simply not being thrown in your thread. system.tag.readBlocking & .writeBlocking are documented to return a list that contains the operation results. That implies that exceptions thrown are converted to status codes and delivered in the list. But logged for forensic follow-up.