Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Unexpected handling of exc_info in structlog v24 when using .exception

Open
#590 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
python
Domain
backend

Research direction

Start by reading BoundLoggerBase._process_event in structlog/_base.py around the cited line, then inspect how the stdlib bound logger handles .exception and how ProcessorFormatter receives the processed event. Reproduce the provided example and trace why the wrapped logger still emits the traceback after exc_info is removed. Done means the output matches the expected single log line; the issue leaves responsibility for the behavior undecided.

Written by the indexing model from the issue text.

Description

stdlib

Hi.

The new handling of the exception level has introduced a somewhat surprising behaviour.

To reproduce

import sys
import structlog


def custom_exception_processor(logger, name, event_dict):
    if "exc_info" in event_dict:
        exc_type, exc_value, exc_tb = sys.exc_info()
        if exc_value is not None:
            event_dict["event"] = str(exc_value)
        del event_dict["exc_info"]
    return event_dict


structlog.configure(processors=[custom_exception_processor,
                                structlog.stdlib.add_log_level,
                                structlog.stdlib.add_logger_name,
                                structlog.dev.ConsoleRenderer(),
                                structlog.stdlib.ProcessorFormatter.wrap_for_formatter],
                    wrapper_class=structlog.stdlib.BoundLogger,
                    logger_factory=structlog.stdlib.LoggerFactory())
logger = structlog.getLogger("test_logger")
try:
    raise ValueError("test")
except ValueError:
    logger.exception("test", exc_info=True)

I would expect the output to simply read:

[error    ] test                           [test_logger]

Instead, it reads:

[error    ] test                           [test_logger]
Traceback (most recent call last):
  File "inconsistent_exc_info.py", line 23, in <module>
    raise ValueError("test")
ValueError: test

The problem is that the wrapped python logger has a default value of exc_info=True for .exception, which does not get overridden.
Not entirely sure whose responsibility it is (processor or bound logger) to handle this case.

It happens here:

# structlog/_base.py:116 (BoundLoggerBase._process_event)

...
        for proc in self._processors:
            event_dict = proc(self._logger, method_name, event_dict)

        if isinstance(event_dict, (str, bytes, bytearray)):
            return (event_dict,), {}

The returned empty dictionary allows the exc_info to be set to True within the Python logger.

Note that in my reproduction example above, it also does not help if I force the event_dict['exc_info'] = False

Happy to hear your thoughts.

Dominant language
Python
Stars
5k
Forks
302
Avg merge
17m
Merged PRs (30d)
4

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from hynek/structlog

All issues in hynek/structlog

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.