So is "fail-fast if you forget to handle an ExceptionGroup" really a
feature? (Do we call this out in the PEP?)

We may believe that "except Exception" is an abuse, but it is too common to
dismiss out of hand. I think if some app has e.g. a main loop where they
repeatedly do something that may fail in many ways (e.g. handle a web
request), catch all errors and then just log the error and continue from
the top, it's a better experience if it logs "ExceptionGroup: <message>
[<list of subexceptions>]" than if it crashes.

There's also code that catches Exception, logs the error and some relevant
data, and then re-raises it. The logged error may go to a more specialized
destination than the generic traceback, and the log message may contain
additional data that's only available in that stack frame.

So I think there are enough serious use cases that we should do what's best
for those use cases, and not try to lecture users about abuse of the idiom.

I don't know what we would have done if we were building Python from
scratch. Possibly we would not have BaseException at all, and the whole
mess would go away. (But there are some good reasons why we introduced
BaseException, so I don't know that that would really be a better overall
experience.)

--Guido



On Thu, Feb 25, 2021 at 2:46 AM Irit Katriel <iritkatr...@googlemail.com>
wrote:

>
>
> On Thu, Feb 25, 2021 at 5:59 AM Guido van Rossum <gu...@python.org> wrote:
>
>>
>> Here's a potentially alternative plan, which is also complex, but doesn't
>> require asyncio or other use cases to define special classes. Let's define
>> two exceptions, BaseExceptionGroup which wraps BaseException instances, and
>> ExceptionGroup which only wraps Exception instances. (Names to be
>> bikeshedded.) They could share a constructor (always invoked via
>> BaseExceptionGroup) which chooses the right class depending on whether
>> there are any non-Exception instances being wrapped -- this would do the
>> right thing for split() and subgroup() and re-raising unhandled exceptions.
>>
>> Then 'except Exception:' would catch ExceptionGroup but not
>> BaseExceptionGroup, so if a group wraps e.g. KeyboardError it wouldn't be
>> caught (even if there's also e.g. a ValueError among the wrapped errors).
>>
>> Pseudo-code:
>>
>> class BaseExceptionGroup(BaseException):
>>     def __new__(cls, msg, errors):
>>         if cls is BaseExceptionGroup and all(isinstance(e, Exception) for
>> e in errors):
>>             cls = ExceptionGroup
>>         return BaseException.__new__(cls, msg, errors)
>>
>> class ExceptionGroup(Exception, BaseExceptionGroup):
>>     pass
>>
>
>
> This could be a valid compromise.
>
> We keep the ability to wrap any exception, while we lose the "fail-fast if
> you forget to handle an ExceptionGroup" feature, which was intended as a
> kindness towards those who abuse "except Exception".
>
> If we adopt this solution then letting an ExceptionGroup escape from code
> that is not supposed to raise it, is not a fatal error, it's just some
> exception like any other.
> So there is no longer a distinction between code that raises
> ExceptionGroups and code that doesn't. Any code can propagate them, like
> any code can raise any other exception.
> Does this mean that more code needs to be aware of the possibility of them
> showing up?  Is that a problem?  Maybe this a simpler state of affairs
> overall.
>
> What would we have done here if we were building Python from scratch?
>
> Irit
>
>
>
>
>
>
>
>

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/45U4VDHH3E7JJNX2L5JCUE4CJJEMFRNH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to