I am trying to build a function that runs only when uncaught exceptions are raised.
A solution that I found online is to override / wrap sys.excepthook
, like this:
import sys
def exception(*args, **kwargs):
print('Uncaught exception was found', args, kwargs)
sys.excepthook = exception
def foo():
bar()
def bar():
raise ValueError('I am an exception. Catch me if you can!')
foo()
If you save the above code into a file and run it using python
, it will print "Uncaught exception was found". And if you add a try/except around bar()
, it doesn't run. This is exactly the functionality that I want.
This even works in an interactive Python shell and using mayapy
. The only situation that I've found it does not work is within Autodesk Maya itself. You can run the above code in the Script Editor, as a menu item, or as a shelf button and it does not run the contents of the exception
function. Oddly enough, it does work in Nuke however (both using its python interpreter and from inside of Nuke).
So to summarize - the above method works by:
python
python
as an interactive shell, pasting the code and running it in theremayapy
mayapy
as an interactive shell, pasting the code and running it in thereAnd doesn't work by:
If there's another, better method to achieve what I want then please let me know. Otherwise, is there a reason why this technique isn't working? Any help would be appreciated.
IMO it would be cleaner to let meddling with excepthook to interactive shells and instead wrapping your main
in a try/except
and then just reraise the exception after your special treatment like so:
def main():
foo()
try:
main()
except Exception as e:
print(f'Uncaught exception was found: {type(e).__name__}: {e}')
raise
But if you like to go with excepthook, this blog describes a solution for maya:
import maya.utils
def myExceptCB(etype, value, tb, detail=2):
# do something here...
print "do something here..."
return maya.utils._formatGuiException(etype, value, tb, detail)
maya.utils.formatGuiException = myExceptCB