-
-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cancelled AsyncResources eat exceptions #1559
Comments
Ah. So that's where these vanish to. I agree, though I do wonder how many false positives a change like that would trigger. |
I really don't like the idea of an exception "teleporting" from the place where the resource is closed up to the place where the Instead, let's consider if there's some way to let the original exception keep propagating through the resource You could make an argument that exceptions coming into class AsyncResource:
async def __aexit__(self, etype, value, tb):
if etype is not None:
with trio.CancelScope(shield=True):
await aclose_forcefully(self)
else:
await self.aclose() I'm not quite sure I understand the full implications of this, though. It's definitely less surprising in the case where you have a ambient cancellation ongoing and a non- Another option would be to say that in class AsyncResource:
async def __aexit__(self, etype, value, tb):
try:
await self.aclose()
except Cancelled:
if etype is not None:
return # let original exception propagate instead
raise This doesn't handle |
I think cancelling Ideally this would be a context manager we expose publicly that people can put around their own async
|
… except when the non-Cancelled exception triggers a cancellation which triggers another exception – which then gets swallowed up by said cancellation. That happens all-too-often in network clients (or servers for that matter) when handling teardown of the connection is … rather less well-tested than we'd like. |
I'd really like to see a code example for that because I can't wrap my head around how it would look |
This is an especially surprising special case of #455.
This code:
will swallow the ValueError, because it gets stuck as the
__context__
of theCancelled
exception raised inany_asyncresource.aclose
. Andaclose
here is basically required to raiseCancelled
, because Trio rules require it to be a checkpoint.This showed up in #1555, with trio.Process standing in for "any_asyncresource".
This kind of thing keeps showing up for me and it's extremely confusing to track down. I know the party line is "who knows if someone was going to handle that exception that got stuck as the Cancelled
__context__
, we shouldn't reraise it when we swallow the Cancelled". But I think sometimes raising an exception that the user thought was handled is a much better failure mode than sometimes silently swallowing an exception that no one tried to handle at all.The text was updated successfully, but these errors were encountered: