Good question. The main use case I see for iterating over individual exceptions is logging frameworks that want to format their own exception tracebacks for whatever reason. I know that the module has extensive utilities for exactly that, but I betcha there are plenty of people who still want to roll their own, e.g. for compatibility with other tooling on their platform.

Presumably the code for traversing a tree of exceptions exists in I honestly don't think it matters much whether we do it as an iterator or using callbacks, as long as it visits all the leaves in the tree.

Hm, a different idea: maybe it's simple enough that we can just add an example showing how to do this? Then people can tailor that e.g. to use various traversal orders. (We could just link to the code in, but it probably is full of distractions.)

On Thu, Feb 25, 2021 at 3:01 AM Irit Katriel <> wrote:

On Thu, Feb 25, 2021 at 5:19 AM Guido van Rossum <> wrote:
[Subthread: handling individual errors]

> Rather than iterator, I think we should add a visitor that calls a function for each leaf exception,

I agree that we shouldn't add an `__iter__` method. But what if we added a separate method that returns an iterator? Then you could write
for e in eg.something():
    print("caught", e)
This looks cleaner to me than having to write
def handler(e):
    print("caught", e)
(Does my bias against callback functions shine through? :-)

I hear you. I suggested a visitor to make it a bit awkward to use because I'm not sure why people should iterate over individual exceptions in an ExceptionGroup, and I think that by providing an iteration utility we are implying that this is what you should do.
So let me be more direct instead of proposing passive-aggressive APIs. 

Can we take a step back and talk about how we think people would want to handle ExceptionGroups?

In the rejected ideas section we discuss this a bit, with a reference to Yury's writeup:

TL;DR:  when you get a group of exceptions from asyncio or the like, you may want to query it for exception types is contains (with subgroup()), you may want to format it into a log (with traceback.* methods), but you are unlikely to care whether there are 1, 2 or 300 ValueErrors. Your program will probably do the same thing regardless. If you allowed your ValueError get collected into an ExceptionGroup you already lost the context in which it happened to it's unlikely that you can make a targeted recovery which is relevant to this particular exception.

So, what is the use case for iterating over single exceptions?

--Guido van Rossum (
Pronouns: he/him (why is my pronoun here?)