Crash reporting, logging uncaught errors and friendly CLI error messages all hook in here.
Inside an except block, sys.exception() (3.11+) returns the exception currently being handled, or None outside one. The older sys.exc_info() returns the triple (type, value, traceback); since 3.11 the type and traceback are always derivable from the value (type(e), e.__traceback__). Library code such as logging helpers uses these to access the exception without being passed it.
When an exception escapes the program, Python calls sys.excepthook(type, value, tb), whose default prints the traceback to stderr. Replace it to change that behaviour:
- Show a one-line message to end users of a CLI, but the full traceback when a
--debugflag is set. - Send crashes to logging or an error-tracking service.
Keep the original in sys.__excepthook__ and call it for cases you don't handle. An excepthook should never raise.
Related hooks:
threading.excepthookhandles exceptions escaping threads, which do not go throughsys.excepthook.sys.unraisablehookreceives exceptions that can't be raised, such as errors in__del__.- In asyncio, use the loop's exception handler.
KeyboardInterrupt also passes through the excepthook, so let it fall back to the default when you only want to reformat ordinary errors.
Example
import subprocess
import sys
try:
{}["missing"]
except KeyError:
e = sys.exception()
print(type(e).__name__, e) # KeyError 'missing'
print(sys.exception()) # None
app = '''
import sys
def hook(exc_type, exc, tb):
if issubclass(exc_type, KeyboardInterrupt):
return sys.__excepthook__(exc_type, exc, tb)
print(f"error: {exc}", file=sys.stderr) # short message, no traceback
sys.excepthook = hook
raise FileNotFoundError("settings.toml not found")
'''
r = subprocess.run([sys.executable, "-c", app], capture_output=True, text=True)
print(r.returncode, r.stderr.strip()) # 1 error: settings.toml not foundRemember
sys.exception()returns the exception being handled (3.11+)- Assign
sys.excepthookto control how uncaught exceptions are reported - Threads use
threading.excepthook; delegate unknown cases tosys.__excepthook__
Watch out for
- Expecting a custom
sys.excepthookto catch errors raised in worker threads.