Running system.db.runUpdateQuery inside try/except clause, if the code is failed by sql (e.g. wrong data format, duplicate name, etc.), try/except fails to handle the SQL thrown exceptions, is this as expected?
Normal jython try:
-- except:
won't trap java exceptions. You often need two except:
clauses, the first being except java.lang.Throwable, t:
or similar.
Some related discussions.
Note that when catching such exceptions in Vision Client scope or Designer scope, the real SQL exception is not available--it won't serialize and the JDBC classes don't exist in those scopes anyways.
Thank you for the prompt help,
@CTavakoli how did you solve it? can you share your python code?
Cheers, Alex
@Alex_SHARIKOV below is a sample code:
Please remove the screenshot. Put your pasted text of your code back in place. Highlight it all. Then click the "Preformatted Text" button in the comment editor. That will make a nicely formatted code block with all the nice features.
I think it would be cleaner like this
from java.lang import Throwable
results = {"success": None, "error": None}
try:
results["success"] = something_to_try()
except Exception, e:
results["error"] = e
except Throwable, t:
results["error"] = t
return results
If you're catching Throwable
and doing the same thing, there's no reason to catch Exception
first; Exception is a subclass of Throwable.
No, Exception
in this usage is jython's Exception
. Sneaky. I like it. (This is what I do, too.)
Thanks @dkhayes117 and @CTavakoli
Sorry for long replay
I had different requirements for my error handling mechanism. The requirements:
- It should look clean in the View component:
a. only oneexcept
clause so it’s easily repeated in other components (less code duplication)
b. the error handling happens in the standalone script - Error handling
raise
depends on the location of the error occurred:
a. If an error occurred during development in Designer it needs to show the Native Error Window.
b. If an error occurred during usage by an Operator it needs to display the error on the screen, so the Operator can copy/screenshot it and send it to the developers.
I posted my solution in another thread, and also see below with some comments. Your requirements must be different, so it's just for information only:
Perspective View Component script:
def runAction(self, event):
try:
# some nested script with an error when calling system.db.runUpdateQuery(query)
db_helper.call_update_db_with_error()
except:
# this will catch all type of exceptions and pass it to the .error() function
utils.error(self)
Custom script module in Scripting:
def error(_self):
# this provides the information on type and stack trace of the exception
ex_type, ex, stacktrace = sys.exc_info()
# check if exception raised by Java Throwable
is_java_ex = type(ex_type) == type(java.lang.Exception)
cause = str(ex.getCause()) + ' ***** ' if is_java_ex else ''
# check if it was cased during the development so send back to the Designer with the cause
if _self.session.props.device.type == 'designer':
raise Exception, (cause, ex), stacktrace
# else: show it on the operator screen for sending it to the developers
trigger = ' ***** by ' + _self.name + ' from ' + _self.page.props.path
message = cause + traceback.format_exc() + trigger
params = {'message': message}
log(message, 'error')
system.perspective.openPopup(
'random_id',
'Popup/ErrorMessage',
params=params,
title='EXECUTION ERROR: Contact developers',
modal=True
)
You could get really fancy, and add a decorator implementation, so that you can do something like:
@handle_errors
db_helper.call_update_db_with_error
Probably overkill, though.
I like this idea and I don't think it is an overkill if it helps my productivity:
it's just I have a basic knowledge of decorator
s so It looks like I have to decorate the most of my db_helper
functions. That might create a problem of throwing an error too early when I have a nested execution of the functions in the db_helper
or other script modules and I'll lose the stack trace.
But, not too sure, haven't tried it yet.