# Custom sys.excepthook in Ignition

**URL:** <https://forum.inductiveautomation.com/t/custom-sys-excepthook-in-ignition/68002>\
**Category:** Ignition\
**Tags:** ignition81, scripting\
**Created:** [December 27, 2022, 5:29pm UTC](https://forum.inductiveautomation.com/t/custom-sys-excepthook-in-ignition/68002 "2022-12-27T17:29:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![chandler](https://avatars.discourse-cdn.com/v4/letter/c/e9a140/32.png) [@chandler](https://forum.inductiveautomation.com/u/chandler)\
**Post date:** [December 27, 2022, 5:29pm UTC](https://forum.inductiveautomation.com/t/custom-sys-excepthook-in-ignition/68002/1 "2022-12-27T17:29:38Z")

</div>

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:

```auto
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

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [December 27, 2022, 5:36pm UTC](https://forum.inductiveautomation.com/t/custom-sys-excepthook-in-ignition/68002/2 "2022-12-27T17:36:07Z")

</div>

Hmm. Quite the rabbit hole. Please report what you find.

---

<div class="post-metadata">

**Author:** ![chandler](https://avatars.discourse-cdn.com/v4/letter/c/e9a140/32.png) [@chandler](https://forum.inductiveautomation.com/u/chandler)\
**Post date:** [December 27, 2022, 7:02pm UTC](https://forum.inductiveautomation.com/t/custom-sys-excepthook-in-ignition/68002/3 "2022-12-27T19:02:18Z")

</div>

@pturmel I was praying you would be the one with the answers to these questions 😉

Anyways,  
I did some testing, and I wasn't able to get my custom exception hook function to run when an exception was thrown. I tried overriding `sys.excepthook` at the beginning of the script that I was using for testing, as well as in the gateway update script, and it seemed to still use the default code in both cases.

I did a not-so-extensive test to try to answer my first question, which involved throwing an exception in one tag value changed script, then throwing a distinguishable exception in another script between when the first script threw its exception and when it called `sys.exc_info()`. The `sys.exc_info()` call still returned the exception that was thrown in script #1, which is the behavior I was hoping for. So for now I am going to use the exception information from that function to get a snapshot of the stack local variables.

There still could be cases where threading causes the wrong exception information to be returned depending on where and when the code is executed, I guess. One place that comes to mind that might be problematic is in gateway timer scripts that have the threading option set to "shared". To be honest I don't feel like testing this out at the moment, but if I do I will post my results on this thread.
