Last active
December 13, 2021 16:55
-
-
Save kojiromike/a719ed8e0ebd424b61484bbd2adecf5b to your computer and use it in GitHub Desktop.
A demonstration of Python exception context and logging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import sys | |
import logging | |
from pprint import pprint | |
LOG = logging.getLogger('Exception Logging Demo') | |
logging.basicConfig(format='[%(asctime)s] %(name)s:%(levelname)s %(message)s', level='INFO') | |
print("This is a demonstration of how Python manages exception information.") | |
print("sys.exc_info() returns a tuple of whatever exception is in the global context.") | |
print("https://docs.python.org/3/library/sys.html#sys.exc_info") | |
print() | |
print("=" * 80) | |
print() | |
print("When there's no exception in context, it looks like this:") | |
print("-" * 80) | |
pprint(sys.exc_info()) | |
print("-" * 80) | |
print() | |
try: | |
raise RuntimeError("A runtime error occurred") | |
except RuntimeError: | |
print("In an exception handler (`except` block), there's an exception in context.") | |
print("(You don't have to name an exception to access it from sys.exc_info().)") | |
print("It looks like this:") | |
print("-" * 80) | |
pprint(sys.exc_info()) | |
print("-" * 80) | |
print() | |
print("Once outside the except block, the exception is no longer in context.") | |
print("Here's sys.exc_info() again:") | |
print("-" * 80) | |
pprint(sys.exc_info()) | |
print() | |
print("=" * 80) | |
print() | |
print("The python logger has a special facility for logging exceptions.") | |
print("When you pass `exc_info=True` to a logger call, it will cause the logger") | |
print("to display the exception from sys.exc_info (if any).") | |
print("With default formatting, it will print the exception message and the traceback.") | |
print("You can also pass a different exception, and of course the logger can be configured") | |
print("to format the exception and its traceback differently.") | |
print("https://docs.python.org/3/library/logging.html#logging.debug") | |
print() | |
print("=" * 80) | |
print() | |
print("-" * 80) | |
LOG.info("logger.info, with no exception in context, exc_info=True", exc_info=True) | |
print("-" * 80) | |
print() | |
try: | |
raise RuntimeError("A second runtime error occurred") | |
except RuntimeError: | |
print("-" * 80) | |
LOG.info("logger.info, with an exception in context, exc_info=True", exc_info=True) | |
print("-" * 80) | |
print() | |
print() | |
print("=" * 80) | |
print("logger.exception is just logger.error with exc_info implicitly set to True") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is a demonstration of how Python manages exception information. | |
sys.exc_info() returns a tuple of whatever exception is in the global context. | |
https://docs.python.org/3/library/sys.html#sys.exc_info | |
================================================================================ | |
When there's no exception in context, it looks like this: | |
-------------------------------------------------------------------------------- | |
(None, None, None) | |
-------------------------------------------------------------------------------- | |
In an exception handler (`except` block), there's an exception in context. | |
(You don't have to name an exception to access it from sys.exc_info().) | |
It looks like this: | |
-------------------------------------------------------------------------------- | |
(<class 'RuntimeError'>, | |
RuntimeError('A runtime error occurred'), | |
<traceback object at 0x110680f80>) | |
-------------------------------------------------------------------------------- | |
Once outside the except block, the exception is no longer in context. | |
Here's sys.exc_info() again: | |
-------------------------------------------------------------------------------- | |
(None, None, None) | |
================================================================================ | |
The python logger has a special facility for logging exceptions. | |
When you pass `exc_info=True` to a logger call, it will cause the logger | |
to display the exception from sys.exc_info (if any). | |
With default formatting, it will print the exception message and the traceback. | |
You can also pass a different exception, and of course the logger can be configured | |
to format the exception and its traceback differently. | |
https://docs.python.org/3/library/logging.html#logging.debug | |
================================================================================ | |
-------------------------------------------------------------------------------- | |
[2021-12-13 11:55:15,556] Exception Logging Demo:INFO logger.info, with no exception in context, exc_info=True | |
NoneType: None | |
-------------------------------------------------------------------------------- | |
-------------------------------------------------------------------------------- | |
[2021-12-13 11:55:15,556] Exception Logging Demo:INFO logger.info, with an exception in context, exc_info=True | |
Traceback (most recent call last): | |
File "/Users/michaelsmith/dev/minerva-service/./exc_info_demo.py", line 60, in <module> | |
raise RuntimeError("A second runtime error occurred") | |
RuntimeError: A second runtime error occurred | |
-------------------------------------------------------------------------------- | |
================================================================================ | |
logger.exception is just logger.error with exc_info implicitly set to True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment