I have been looking for a way to log local variable values from the current function as well as further down the call stack under certain circumstances in my code. I looked at using sys.exc_info() to get a traceback object, then logging the locals from each stack frame using that object. I read in the docs that sys.exc_info() is not thread safe. This leads me to my first question:
Will Ignition's threading potentially cause sys.exc_info() to return information about an exception that happened between the exception that I care about and the call to sys.exc_info()?
Because of the thread safety concerns I did some more digging and found out about the ability to override the code that gets executed when an uncaught exception is raised using sys.excepthook. My thought was that since this would be called for each exception, it would alleviate the thread safety issues posed by sys.exc_info(). I was thinking about overriding it like this:
def customExceptHook(cls, inst, tb):
if ... # logic to determine if this is an exception that I want to log stack locals for
logTb = tb
while logTb:
log(logTb.tb_frame.f_locals)
logTb = logTb.tb_next
# call the default excepthook to keep default behavior when an exception occurs.
sys.__excepthook__(cls, inst, tb)
Since it would call the default except hook after logging the information I want, it seems like it shouldn't break any functionality that already happens when an exception occurs.
This leads me to my last two questions:
Are there any implications with overriding sys.excepthook that I may have missed including Ignition specific things, or Jython specific things?
If I were to implement this, where should I do the override to make sure it is overridden through any gateway restarts, scripting restarts, etc? (I was thinking in the gateway on update script)
edit: realized a problem with my function. It needs to pass the original tb to the sys.__excepthook__ function