Consider this Python code:


try:
    1 / 0
except Exception as e:
    logger.error("An error occurred while dividing by zero.: %s", e)

The output of this is:


An error occurred while dividing by zero.: division by zero

No traceback. Perhaps you don't care because you don't need it.
I see code like this quite often and it's curious that you even use logger.error if it's not a problem. And it's curious that you include the stringified exception into the logger message.

Another common pattern I see is use of exc_info=True like this:


try:
    1 / 0
except Exception:
    logger.error("An error occurred while dividing by zero.", exc_info=True)

Its output is:


An error occurred while dividing by zero.
Traceback (most recent call last):
  File "/Users/peterbengtsson/dummy.py", line 23, in <module>
    1 / 0
    ~~^~~
ZeroDivisionError: division by zero

Ok, now you get the traceback and the error value (division by zero in this case).

But a more convenient function is logger.exception which looks like this:


try:
    1 / 0
except Exception:
    logger.exception("An error occurred while dividing by zero.")

Its output is:


An error occurred while dividing by zero.
Traceback (most recent call last):
  File "/Users/peterbengtsson/dummy.py", line 9, in <module>
    1 / 0
    ~~^~~
ZeroDivisionError: division by zero

So it's sugar for logger.error.

Also, a common logging config is something like this:

import logging

logger = logging.getLogger(__name__)
logging.basicConfig(
    format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", level=logging.ERROR
)

So if you use logger.exception what will it print? In short, the same as if you used logger.error. For example, with the logger.exception("An error occurred while dividing by zero.") line above:


2026-03-06 10:45:23,570 - ERROR - __main__ - An error occurred while dividing by zero.
Traceback (most recent call last):
  File "/Users/peterbengtsson/dummy.py", line 12, in <module>
    1 / 0
    ~~^~~
ZeroDivisionError: division by zero

Bonus - add_note

You can, if it's applicable, inject some more information about the exception. Consider:


try:
    n / 0
except Exception as exception:
    exception.add_note(f"The numerator was {n}.")
    logger.exception("An error occurred while dividing by zero.")

The net output of this is:


2026-03-06 10:48:34,279 - ERROR - __main__ - An error occurred while dividing by zero.
Traceback (most recent call last):
  File "/Users/peterbengtsson/dummy.py", line 13, in <module>
    1 / 0
    ~~^~~
ZeroDivisionError: division by zero
The numerator was 123.

Your email will never ever be published.

Previous:
How to find which git SHA it was when you merged in the default branch February 26, 2026 Linux, Git
Next:
Copy the current line in VS Code March 12, 2026 macOS
Related by category:
Claude Opus is 10x faster than OpenAI GPT 5 at non-streaming completions July 24, 2026 Python
Best Django Redis configuration for speed and size July 19, 2026 Python
How to use a list/tuple/array in Django with a raw SQL cursor July 14, 2026 Python
Using AI to rewrite blog post comments November 12, 2025 Python
Related by keyword:
How to log ALL PostgreSQL SQL happening July 20, 2015 PostgreSQL, macOS
Chainable catches in a JavaScript promise November 5, 2015 Web development, JavaScript
Careful with your assertRaises() and inheritance of exceptions April 10, 2013 Python
pg_class to check if table exists April 20, 2005 Linux