{"action":"created","issue":{"url":"https://api.github.com/repos/python-trio/trio/issues/800","repository_url":"https://api.github.com/repos/python-trio/trio","labels_url":"https://api.github.com/repos/python-trio/trio/issues/800/labels{/name}","comments_url":"https://api.github.com/repos/python-trio/trio/issues/800/comments","events_url":"https://api.github.com/repos/python-trio/trio/issues/800/events","html_url":"https://github.com/python-trio/trio/issues/800","id":389718837,"node_id":"MDU6SXNzdWUzODk3MTg4Mzc=","number":800,"title":"MultiError sad story","user":{"login":"belm0","id":1708631,"node_id":"MDQ6VXNlcjE3MDg2MzE=","avatar_url":"https://avatars3.githubusercontent.com/u/1708631?v=4","gravatar_id":"","url":"https://api.github.com/users/belm0","html_url":"https://github.com/belm0","followers_url":"https://api.github.com/users/belm0/followers","following_url":"https://api.github.com/users/belm0/following{/other_user}","gists_url":"https://api.github.com/users/belm0/gists{/gist_id}","starred_url":"https://api.github.com/users/belm0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/belm0/subscriptions","organizations_url":"https://api.github.com/users/belm0/orgs","repos_url":"https://api.github.com/users/belm0/repos","events_url":"https://api.github.com/users/belm0/events{/privacy}","received_events_url":"https://api.github.com/users/belm0/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-12-11T11:28:51Z","updated_at":"2018-12-11T23:39:45Z","closed_at":null,"author_association":"MEMBER","body":"I know there are plans to have nursery raise MultiError exclusively, but I'll share this story.\r\n\r\nA nursery is wrapped in a try/catch naively catching a bare exception.  Works fine, except when an enclosing move_on_after() happens to reach its deadline simultaneously with an exception within the nursery.\r\n\r\nWhat made it so hard to debug is that the final exception trace has no mention of MultiError, only the bare exception.  Which made it seem like the `except` clause was mysteriously ignored.\r\n\r\nHere is the repro I used to understand this:\r\n\r\n```\r\nfrom random import uniform\r\nimport trio\r\n\r\ncount = 0\r\n\r\nasync def raiser():\r\n    await trio.sleep(30 / 1000)\r\n    raise ValueError('foo')\r\n\r\nasync def async_main():\r\n    global count\r\n    while True:\r\n        count += 1\r\n        with trio.move_on_after(uniform(20, 40) / 1000):\r\n            try:\r\n                # The following nursery will sometimes leak a ValueError\r\n                # despite the try/except.\r\n                async with trio.open_nursery() as nursery:\r\n                    nursery.start_soon(raiser)\r\n                    await trio.sleep_forever()\r\n                # If replace with a direct call to raiser() it doesn't occur.\r\n                #await raiser()\r\n            except ValueError:\r\n                pass\r\n            except BaseException as e:\r\n                print(type(e), e)\r\n                raise\r\n\r\ntry:\r\n    trio.run(async_main)\r\nexcept KeyboardInterrupt:\r\n    pass\r\nfinally:\r\n    print('count:', count)\r\n```\r\n\r\n```\r\n<class 'trio.MultiError'> Cancelled(), Cancelled(), Cancelled()\r\n<class 'trio.MultiError'> Cancelled(), Cancelled(), Cancelled()\r\n...\r\n<class 'trio.MultiError'> ValueError('foo',), Cancelled()\r\ncount: 29\r\nTraceback (most recent call last):\r\n  File \"main.py\", line 30, in <module>\r\n    trio.run(async_main)\r\n  File \"/.../site-packages/trio/_core/_run.py\", line 1337, in run\r\n    raise runner.main_task_outcome.error\r\n  File \"main.py\", line 27, in async_main\r\n    raise\r\n  File \"/.../site-packages/trio/_core/_ki.py\", line 165, in wrapper\r\n    return fn(*args, **kwargs)\r\n  File \"/.../site-packages/trio/_core/_run.py\", line 260, in __exit__\r\n    raise remaining_error_after_cancel_scope\r\n  File \"main.py\", line 20, in async_main\r\n    await trio.sleep_forever()\r\n  File \"/.../site-packages/trio/_core/_run.py\", line 397, in __aexit__\r\n    raise combined_error_from_nursery\r\n  File \"main.py\", line 8, in raiser\r\n    raise ValueError('foo')\r\nValueError: foo\r\n```"},"comment":{"url":"https://api.github.com/repos/python-trio/trio/issues/comments/446405009","html_url":"https://github.com/python-trio/trio/issues/800#issuecomment-446405009","issue_url":"https://api.github.com/repos/python-trio/trio/issues/800","id":446405009,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0NjQwNTAwOQ==","user":{"login":"Zac-HD","id":12229877,"node_id":"MDQ6VXNlcjEyMjI5ODc3","avatar_url":"https://avatars1.githubusercontent.com/u/12229877?v=4","gravatar_id":"","url":"https://api.github.com/users/Zac-HD","html_url":"https://github.com/Zac-HD","followers_url":"https://api.github.com/users/Zac-HD/followers","following_url":"https://api.github.com/users/Zac-HD/following{/other_user}","gists_url":"https://api.github.com/users/Zac-HD/gists{/gist_id}","starred_url":"https://api.github.com/users/Zac-HD/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Zac-HD/subscriptions","organizations_url":"https://api.github.com/users/Zac-HD/orgs","repos_url":"https://api.github.com/users/Zac-HD/repos","events_url":"https://api.github.com/users/Zac-HD/events{/privacy}","received_events_url":"https://api.github.com/users/Zac-HD/received_events","type":"User","site_admin":false},"created_at":"2018-12-11T23:39:45Z","updated_at":"2018-12-11T23:39:45Z","author_association":"MEMBER","body":"(FYI @belm0 you can [syntax-highlight code blocks](https://help.github.com/articles/creating-and-highlighting-code-blocks/) for `python` and `python-traceback`)"}}
{"actor":{"display_login":"Zac-HD"}}