Inconsistent "timeout" exceptions for system.util.sendRequest

Hi,

Not sure if this is a bug or not: when a request to a remote gateway times out, the exceptions that are raised are inconsistent.

Most of the time a com.inductiveautomation.metro.api.ex.TimeoutExpiredException is thrown

Java Exception: <type 'com.inductiveautomation.metro.api.ex.TimeoutExpiredException'>
TimeoutExpiredException[queueId=scriptMsgQueue, targetIntent=PLATFORM_SCRIPT_REQ, msgData=com.inductiveautomation.ignition.gateway.clientcomm.scriptmsg.RemoteScriptMsg@7146e0f]

but occasionally a java.util.concurrent.TimeoutException is thrown instead, using the exact same request.

Java Exception: <type 'java.util.concurrent.TimeoutException'>
java.util.concurrent.TimeoutException: Timeout has expired for sendRequest operation

This makes it quite annoying to consistently and unambiguously catch a timeout exception (which is normally a transient error).

My test setup consists of a bare perspective view, containing only a TextArea and a OneShotButton. The onActionPerformed code for the button is below.

Code
	out = self.getSibling("TextArea")
	out.props.text = "Busy ..."
	
	import java.lang.Throwable
	
	_remoteServer = "OT01"
	_project = "Redacted"
	_messageHandler = "Product"
	_timeoutSec = 2
	
	payload = {"action": "getById", "id": '784a4eca-1383-41b1-affb-b862356ed269'}
	
	try:
		response = system.util.sendRequest(_project, _messageHandler, payload, _remoteServer, _timeoutSec)
		out.props.text = repr(response)
	except java.lang.Throwable as t:
		out.props.text = "Java Exception: {}\n{}".format(t.getClass(), repr(t))
	except Exception as e:
		out.props.text = "Python Error: {}\n{}".format(e.__name__, repr(e))
	finally:
		self.props.value = 0

We're running Ignition 8.1.36 on Windows Server 2019. The "OT01" gateway connection is configured in the settings, but is disabled to simulate this error.

A Metro timeout indicates the request over the gateway network failed.
A "plain" timeout means the request to the local gateway the designer/client is connected to failed.

The request always has to go through the local gateway before it can reach the remote, so two different timeouts. But you should be able to catch both within a single exception block using the tuple syntax?

Ah, makes sense, and good to know that there is this distinction.

My current solution is indeed to wrap the sendRequest call in a separate function, catching these two exceptions there and re-raising them as a custom Python error.