tnetwork: handle main_taskgroup dying better. passthrough CancelledError - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 9e57a5961554a8c550868127f0a10d72327da4b8 DIR parent 6197cfbb3b00f21fb01fd8ef95a849eb63fc9253 HTML Author: SomberNight <somber.night@protonmail.com> Date: Fri, 30 Aug 2019 19:46:25 +0200 network: handle main_taskgroup dying better. passthrough CancelledError Previously if a task running in the main_taskgroup raised, main_taskgroup might have never finished as fx.run (another task running in main_taskgroup) could not be cancelled (it was swallowing the CancelledError). Need to be careful with catching all Exceptions or BaseExceptions, as that might result in a coroutine not being cancellable. Note that from python 3.8 onwards, CancelledError will inherit from BaseException instead of Exception, so catching all Exceptions is somewhat less horrible but this will only really matter if we raise the min py version to 3.8... Really, all "except BaseException" lines are suspect and at least should be considered for replacement with "except Exception". ----- regarding fx.run not being cancellable before, and relevant lines, see: https://github.com/spesmilo/electrum/blob/6197cfbb3b00f21fb01fd8ef95a849eb63fc9253/electrum/network.py#L1171 https://github.com/kyuupichan/aiorpcX/blob/0decdffce20aec217e9b4506ea20a0919994cea0/aiorpcx/curio.py#L242 https://github.com/kyuupichan/aiorpcX/blob/0decdffce20aec217e9b4506ea20a0919994cea0/aiorpcx/curio.py#L199 https://github.com/kyuupichan/aiorpcX/blob/0decdffce20aec217e9b4506ea20a0919994cea0/aiorpcx/curio.py#L208 https://github.com/kyuupichan/aiorpcX/blob/0decdffce20aec217e9b4506ea20a0919994cea0/aiorpcx/curio.py#L218 https://github.com/kyuupichan/aiorpcX/blob/0decdffce20aec217e9b4506ea20a0919994cea0/aiorpcx/curio.py#L221 https://github.com/spesmilo/electrum/blob/6197cfbb3b00f21fb01fd8ef95a849eb63fc9253/electrum/daemon.py#L194 https://github.com/spesmilo/electrum/blob/6197cfbb3b00f21fb01fd8ef95a849eb63fc9253/electrum/daemon.py#L203 https://github.com/spesmilo/electrum/blob/6197cfbb3b00f21fb01fd8ef95a849eb63fc9253/electrum/exchange_rate.py#L507 https://github.com/spesmilo/electrum/blob/6197cfbb3b00f21fb01fd8ef95a849eb63fc9253/electrum/exchange_rate.py#L79 Diffstat: M electrum/exchange_rate.py | 3 +++ M electrum/network.py | 4 ++-- M electrum/util.py | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) --- DIR diff --git a/electrum/exchange_rate.py b/electrum/exchange_rate.py t@@ -78,6 +78,9 @@ class ExchangeBase(Logger): self.logger.info(f"getting fx quotes for {ccy}") self.quotes = await self.get_rates(ccy) self.logger.info("received fx quotes") + except asyncio.CancelledError: + # CancelledError must be passed-through for cancellation to work + raise except BaseException as e: self.logger.info(f"failed fx quotes: {repr(e)}") self.quotes = {} DIR diff --git a/electrum/network.py b/electrum/network.py t@@ -1169,8 +1169,8 @@ class Network(Logger): async with main_taskgroup as group: await group.spawn(self._maintain_sessions()) [await group.spawn(job) for job in self._jobs] - except Exception as e: - self.logger.exception('') + except BaseException as e: + self.logger.exception('main_taskgroup died.') raise e asyncio.run_coroutine_threadsafe(main(), self.asyncio_loop) DIR diff --git a/electrum/util.py b/electrum/util.py t@@ -983,7 +983,9 @@ def ignore_exceptions(func): async def wrapper(*args, **kwargs): try: return await func(*args, **kwargs) - except BaseException as e: + except asyncio.CancelledError: + raise + except Exception as e: pass return wrapper