Skip to content

bpo-36916: Swallow unhandled exception #13313

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

Merged
merged 3 commits into from
May 14, 2019

Conversation

asvetlov
Copy link
Contributor

@asvetlov asvetlov commented May 14, 2019

The PR fixes a message about an unhandled exception in a task when writer.write() is used without await but writer.drain() fails with an exception.

https://bugs.python.org/issue36916

# Do a trick to suppress unhandled exception
# if stream.write() was used without await and
# stream.drain() was paused and resumed with an exception
task.exception()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silently ignore exceptions looks like a bad idea. If the task failed, the exception should be at least logged.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a special case here.
Basically, there are two ways to call write() now:

  1. Legacy writer.write(b'data')
  2. Recommended await writer.write(b'data')

For the second case, an exception raised by nested writer.drain() call is propagated to user.
The first case ignores the exception from nested writer.drain() call, allowing existing code to work in a backward compatible way.
A subsequent call to drain() raises the exception again, like in the following snippet:

writer.write(b'data')  # exception is swallowed
await writer.drain()  # previous exception is raised if any

Sorry for such a tricky code.
Ideally, we should make writer.write() a coroutine from the very beginning.
Proposed workaround is a strategy to keep backward compatibility and provide a smooth transition path.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

writer.write(b'data') # exception is swallowed

Again, this exception should be logged somehow. It's a bad practice to silently ignore exceptions and don't provide any way to the developer to see these exceptions.

Can you try to write the exception?

I only merged your PR only to attempt to fix https://bugs.python.org/issue36870

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to do exactly the opposite than your PR :-) Provide a way to get ignored exceptions: #13187 :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it is not for suppressing an exception entirely, the exception is raised to the caller on await writer.write() if this form of call is used.
It is for disabling the exception logging. We do similar things in asyncio somewhere.

@bedevere-bot
Copy link

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

@asvetlov
Copy link
Contributor Author

I have made the requested changes; please review again.

Well, actually I did nothing but provide a comment that describes why ignoring the exception in this particular case is ok.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@vstinner: please review the changes made to this pull request.

@vstinner
Copy link
Member

Honestly, I don't understand how it can be a good idea to silently ignore errors. But this PR fix the warning on my Windows VM when running test_drain_raises() on Windows, so I approved it.

My main concern right now is that https://bugs.python.org/issue36870 is breaking the Python CI and the Python workflow.

@vstinner vstinner merged commit f12ba7c into python:master May 14, 2019
@asvetlov asvetlov deleted the swallow-unhandled-exception branch May 14, 2019 16:12
@asvetlov
Copy link
Contributor Author

Thanks, @vstinner
Regarding random fails: looks like the current asyncio code showed the problem that existed for a long time already.
Please let me warm up my Windows VM, I'll cope with it.

@1st1
Copy link
Member

1st1 commented May 14, 2019

@vstinner Please don't merge asyncio PRs without my review. This one looks fine though.

@vstinner
Copy link
Member

@vstinner Please don't merge asyncio PRs without my review. This one looks fine though.

test_asyncio was causing a lot of troubles, please see https://bugs.python.org/issue36870 for the context.

@asvetlov: Can you please also fix Python 3.7? Python 3.7 is also affected by https://bugs.python.org/issue36870

@vstinner
Copy link
Member

By the way, it's not the first time that the Python CI and the Python workflow is broken by test_asyncio, especially by random failures on Windows. I'm not sure how to prevent these issues.

The policy for the CI is to revert a change which introduces a regression: https://pythondev.readthedocs.io/ci.html#revert-on-fail

That's what I did: PR #13316. But @asvetlov asked me to look at this PR instead.

@miss-islington
Copy link
Contributor

Thanks @asvetlov for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington
Copy link
Contributor

Sorry, @asvetlov and @vstinner, I could not cleanly backport this to 3.7 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker f12ba7cd0a7370631214ac0b337ab5455ce717b2 3.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants