Just to clear up what @PGriffith mentioned with an example - I am using the following code that will fail the query due to a a UNIQUNESS constraint.
def throwsError():
import java.lang.Throwable
logger = system.util.getLogger("TEST")
try:
system.db.runUpdateQuery("INSERT INTO listcustomers (name, companyTypeId) VALUES ('Atlas', 1)")
except java.lang.Throwable, e:
logger.error(str(e))
logger.error(str(e.cause))
When I run it on the gateway via a message handler or a tag change even I see the actual error fro the JBDC (the database connection library) -
This is what you saw - so you must be running that function on gateway context via a timer script or tag change or message handler etc. In this scenario, yes you should be able to do something like
import com.microsoft.sqlserver.jdbc.SQLServerException
try:
#something
except com.microsoft.sqlserver.jdbc.SQLServerException:
pass #we don't mind this type of error
There is a catch here. If you now take this function, put it on a button in vision and try to run it, you'll get an import error that there is no microsoft
package. Because that doesn't exist in the local client scope. The error you get from running it locally looks like this -
14:26:49.164 [SwingWorker-pool-1-thread-1] ERROR TEST - java.lang.Exception: Error executing system.db.runUpdateQuery(INSERT INTO listcustomers (name, companyTypeId) VALUES ('Atlas', 1), , , false)
14:26:49.164 [SwingWorker-pool-1-thread-1] ERROR TEST - com.inductiveautomation.ignition.client.gateway_interface.GatewayException: SQL error for "INSERT INTO listcustomers (name, companyTypeId) VALUES ('Atlas', 1)": (conn=661) Duplicate entry 'Atlas' for key 'Name'
Note that this time the error comes through as com.inductiveautomation.ignition.client.gateway_interface.GatewayException
. So even if you could import com.microsoft.blah.blah
you wouldn't catch it on your button press in vision.
That's why my suggested solution is to use java.lang.Throwable
. All java errors (which all db thrown errors are) are sublcasses of java.lang.Throwable
so except java.lang.Throwable, e
will catch it regardless of it is in your gateway scope or your vision\designer scope. Notice too that the error text (outside of the error name) is identical in the e.cause
- SQL error for "INSERT INTO listcustomers (name, companyTypeId) VALUES ('Atlas', 1)": (conn=661) Duplicate entry 'Atlas' for key 'Name'
.
So doing something like
def LoadWrkTable():
try:
call = system.db.createSProcCall("dbo.Load_Wrk_Orders_ItemMast", db_name)
call.registerInParam(1, system.db.DATE, system.date.format(system.date.now(), 'yyyy-MM-dd HH:mm:ss'))
call.registerInParam(2, system.db.VARCHAR,'Host')
system.db.execSProcCall(call)
except java.lang.Throwable, e:
if "Cannot insert duplicate key in object" in str(e.cause):
pass
else:
raise e
except Exception as e:
print("Error details:", str(e))
The above will now work regardless of where you call it from because you're not relying on the jbdc error which you only get on the gateway, but by inspecting the error text itself which is identical in both scopes, and your java.lang.Throwable catches the error in both scopes.