Being able to get the right error/exception?

I have a simple function to return some info about columns in a database table.

def getDBColumnInfo(tableName):
	"""
	Fetchs the columns from the database and returns them as a list of strings
	Args:
		tableName: str, name of database table
	Returns:
		list of tuples of strings of column names of the form
		("column name", "type", "nulls allowed?")
	"""
	import system.db
	ds = system.db.runQuery("DESCRIBE %s"%(tableName))
	l = []
	for row in ds:
		l.append((row[0], row[1], row[2]))
	return l

Just tested it and it worked. I wanted to see what happens when I do a table that doesn’t exist in the database and I get this error stack

Java Traceback:


	at org.python.core.Py.JavaError(Py.java:495)

	at com.inductiveautomation.ignition.common.script.builtin.AbstractDBUtilities.error(AbstractDBUtilities.java:364)

	at com.inductiveautomation.ignition.common.script.builtin.AbstractDBUtilities.runQuery(AbstractDBUtilities.java:335)

	at sun.reflect.GeneratedMethodAccessor330.invoke(Unknown Source)

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.lang.reflect.Method.invoke(Unknown Source)

	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:186)

	at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:435)

	at org.python.core.PyObject.__call__(PyObject.java:387)

	at org.python.core.PyObject.__call__(PyObject.java:391)

	at org.python.pycode._pyx464.getDBColumnInfo$1(<module:app.db>:24)

	at org.python.pycode._pyx464.call_function(<module:app.db>)

	at org.python.core.PyTableCode.call(PyTableCode.java:165)

	at org.python.core.PyBaseCode.call(PyBaseCode.java:134)

	at org.python.core.PyFunction.__call__(PyFunction.java:317)

	at org.python.pycode._pyx463.f$0(<buffer>:8)

	at org.python.pycode._pyx463.call_function(<buffer>)

	at org.python.core.PyTableCode.call(PyTableCode.java:165)

	at org.python.core.PyCode.call(PyCode.java:18)

	at org.python.core.Py.runCode(Py.java:1275)

	at org.python.core.Py.exec(Py.java:1319)

	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:215)

	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:89)

	at org.python.util.InteractiveInterpreter.runsource(InteractiveInterpreter.java:70)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$InterpreterWorker.doInBackground(JythonConsole.java:419)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$InterpreterWorker.doInBackground(JythonConsole.java:407)

	at javax.swing.SwingWorker$1.call(Unknown Source)

	at java.util.concurrent.FutureTask.run(Unknown Source)

	at javax.swing.SwingWorker.run(Unknown Source)

	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

	at java.lang.Thread.run(Unknown Source)

Caused by: java.lang.Exception: Error executing system.db.runQuery(DESCRIBE testtable4, , )

	... 31 more

Caused by: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Table 'tab.testtable4' doesn't exist

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:329)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:303)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:260)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.runLimitQuery(GatewayInterface.java:805)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.runQuery(GatewayInterface.java:769)

	at com.inductiveautomation.ignition.client.script.ClientDBUtilities._runQuery(ClientDBUtilities.java:185)

	at com.inductiveautomation.ignition.common.script.builtin.AbstractDBUtilities.runQuery(AbstractDBUtilities.java:331)

	... 29 more

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'tab.testtable4' doesn't exist

	at sun.reflect.GeneratedConstructorAccessor51.newInstance(null)

	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(null)

	at java.lang.reflect.Constructor.newInstance(null)

	at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)

	at com.mysql.jdbc.Util.getInstance(Util.java:386)

	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)

	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)

	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)

	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)

	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)

	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2809)

	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2758)

	at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1612)

	at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)

	at com.inductiveautomation.ignition.gateway.datasource.DelegatingStatement.executeQuery(DelegatingStatement.java:63)

	at com.inductiveautomation.ignition.gateway.datasource.SRConnectionWrapper$SRStatement.executeQuery(SRConnectionWrapper.java:761)

	at com.inductiveautomation.ignition.gateway.servlets.gateway.functions.RunQuery.run(RunQuery.java:99)

	at com.inductiveautomation.ignition.gateway.servlets.gateway.functions.AbstractDBAction.invoke(AbstractDBAction.java:79)

	at com.inductiveautomation.ignition.gateway.servlets.Gateway.doPost(Gateway.java:390)

	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)

	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

	at com.inductiveautomation.ignition.gateway.bootstrap.MapServlet.service(MapServlet.java:85)

	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:837)

	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)

	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)

	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)

	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)

	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1160)

	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)

	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)

	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1092)

	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)

	at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)

	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)

	at org.eclipse.jetty.server.Server.handle(Server.java:518)

	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308)

	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244)

	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)

	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)

	at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)

	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:246)

	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:156)

	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)

	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)

	at java.lang.Thread.run(null)

Traceback (most recent call last):
  File "<buffer>", line 1, in <module>
  File "<module:app.db>", line 20, in getDBColumnInfo
	at com.inductiveautomation.ignition.common.script.builtin.AbstractDBUtilities.error(AbstractDBUtilities.java:364)

	at com.inductiveautomation.ignition.common.script.builtin.AbstractDBUtilities.runQuery(AbstractDBUtilities.java:335)

	at sun.reflect.GeneratedMethodAccessor330.invoke(Unknown Source)

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.lang.reflect.Method.invoke(Unknown Source)


java.lang.Exception: java.lang.Exception: Error executing system.db.runQuery(DESCRIBE testtable4, , )

I saw com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException and thought that would be the error I am catching, so I can raise a error with a useful message to other developers on my team. I tried this -

def getDBColumnInfo(tableName):
	"""
	Fetchs the columns from the database and returns them as a list of strings
	Args:
		tableName: str, name of database table
	Returns:
		list of tuples of strings of column names of the form
		("column name", "type", "nulls allowed?")
	"""
	import system.db
	import com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException
	try:
		ds = system.db.runQuery("DESCRIBE %s"%(tableName))
		l = []
		for row in ds:
			l.append((row[0], row[1], row[2]))
		return l
	except com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
		raise ValueError("Table name does not exist")

but I get

Traceback (most recent call last):
  File "<buffer>", line 1, in <module>
  File "<module:app.db>", line 18, in getDBColumnInfo
ImportError: No module named mysql

In general, how can I use the error stack already given from Ignition to be able to catch the correct error in my own modules? What would I have to change in my code to catch this?

2 Likes

To see the cause I wanted, i had to do

except java.lang.Exception, e:
	print str(e.cause)

which then showed the mysql cause of the issue, but only after saying it was a gateway issue. I think this is good enough for my purposes though, either a database has a table to describe or it doesn’t. Thanks