Browse Source

Merge pull request #4770 from SomberNight/kill_aiosafe

rm aiosafe decorator. instead: log_exceptions and ignore_exceptions
3.3.3.1
ThomasV 6 years ago
committed by GitHub
parent
commit
e573c6d385
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      electrum/address_synchronizer.py
  2. 6
      electrum/exchange_rate.py
  3. 8
      electrum/interface.py
  4. 7
      electrum/network.py
  5. 8
      electrum/plugins/labels/labels.py
  6. 43
      electrum/util.py

2
electrum/address_synchronizer.py

@ -28,7 +28,7 @@ from collections import defaultdict
from . import bitcoin
from .bitcoin import COINBASE_MATURITY, TYPE_ADDRESS, TYPE_PUBKEY
from .util import PrintError, profiler, bfh, VerifiedTxInfo, TxMinedStatus, aiosafe, SilentTaskGroup
from .util import PrintError, profiler, bfh, VerifiedTxInfo, TxMinedStatus
from .transaction import Transaction, TxOutput
from .synchronizer import Synchronizer
from .verifier import SPV

6
electrum/exchange_rate.py

@ -14,7 +14,7 @@ from typing import Sequence
from .bitcoin import COIN
from .i18n import _
from .util import PrintError, ThreadJob, make_dir, aiosafe
from .util import PrintError, ThreadJob, make_dir, log_exceptions
from .util import make_aiohttp_session
from .network import Network
@ -58,7 +58,7 @@ class ExchangeBase(PrintError):
def name(self):
return self.__class__.__name__
@aiosafe
@log_exceptions
async def update_safe(self, ccy):
try:
self.print_error("getting fx quotes for", ccy)
@ -89,7 +89,7 @@ class ExchangeBase(PrintError):
self.on_history()
return h
@aiosafe
@log_exceptions
async def get_historical_rates_safe(self, ccy, cache_dir):
try:
self.print_error("requesting fx history for", ccy)

8
electrum/interface.py

@ -34,7 +34,7 @@ from collections import defaultdict
import aiorpcx
from aiorpcx import ClientSession, Notification
from .util import PrintError, aiosafe, bfh, AIOSafeSilentException, SilentTaskGroup
from .util import PrintError, ignore_exceptions, log_exceptions, bfh, SilentTaskGroup
from . import util
from . import x509
from . import pem
@ -146,9 +146,6 @@ class Interface(PrintError):
self.tip_header = None
self.tip = 0
# note that an interface dying MUST NOT kill the whole network,
# hence exceptions raised by "run" need to be caught not to kill
# main_taskgroup! the aiosafe decorator does this.
asyncio.run_coroutine_threadsafe(
self.network.main_taskgroup.spawn(self.run()), self.network.asyncio_loop)
self.group = SilentTaskGroup()
@ -249,7 +246,8 @@ class Interface(PrintError):
self.got_disconnected.set_result(1)
return wrapper_func
@aiosafe
@ignore_exceptions # do not kill main_taskgroup
@log_exceptions
@handle_disconnect
async def run(self):
try:

7
electrum/network.py

@ -40,7 +40,7 @@ import dns.resolver
from aiorpcx import TaskGroup
from . import util
from .util import PrintError, print_error, aiosafe, bfh, SilentTaskGroup
from .util import PrintError, print_error, log_exceptions, ignore_exceptions, bfh, SilentTaskGroup
from .bitcoin import COIN
from . import constants
from . import blockchain
@ -478,7 +478,7 @@ class Network(PrintError):
addr = host
return socket._getaddrinfo(addr, *args, **kwargs)
@aiosafe
@log_exceptions
async def set_parameters(self, net_params: NetworkParameters):
proxy = net_params.proxy
proxy_str = serialize_proxy(proxy)
@ -619,7 +619,8 @@ class Network(PrintError):
await self._close_interface(interface)
self.trigger_callback('network_updated')
@aiosafe
@ignore_exceptions # do not kill main_taskgroup
@log_exceptions
async def _run_new_interface(self, server):
interface = Interface(self, server, self.config.path, self.proxy)
timeout = 10 if not self.proxy else 20

8
electrum/plugins/labels/labels.py

@ -9,7 +9,7 @@ import base64
from electrum.plugin import BasePlugin, hook
from electrum.crypto import aes_encrypt_with_iv, aes_decrypt_with_iv
from electrum.i18n import _
from electrum.util import aiosafe, make_aiohttp_session
from electrum.util import log_exceptions, ignore_exceptions, make_aiohttp_session
class LabelsPlugin(BasePlugin):
@ -58,7 +58,8 @@ class LabelsPlugin(BasePlugin):
# Caller will write the wallet
self.set_nonce(wallet, nonce + 1)
@aiosafe
@ignore_exceptions
@log_exceptions
async def do_post_safe(self, *args):
await self.do_post(*args)
@ -129,7 +130,8 @@ class LabelsPlugin(BasePlugin):
self.set_nonce(wallet, response["nonce"] + 1)
self.on_pulled(wallet)
@aiosafe
@ignore_exceptions
@log_exceptions
async def pull_safe_thread(self, wallet, force):
await self.pull_thread(wallet, force)

43
electrum/util.py

@ -846,29 +846,36 @@ def make_dir(path, allow_symlink=True):
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
class AIOSafeSilentException(Exception): pass
def aiosafe(f):
# save exception in object.
# f must be a method of a PrintError instance.
# aiosafe calls should not be nested
async def f2(*args, **kwargs):
self = args[0]
def log_exceptions(func):
"""Decorator to log AND re-raise exceptions."""
assert asyncio.iscoroutinefunction(func), 'func needs to be a coroutine'
async def wrapper(*args, **kwargs):
self = args[0] if len(args) > 0 else None
try:
return await f(*args, **kwargs)
except AIOSafeSilentException as e:
self.exception = e
return await func(*args, **kwargs)
except asyncio.CancelledError as e:
self.exception = e
raise
except BaseException as e:
self.exception = e
self.print_error("Exception in", f.__name__, ":", e.__class__.__name__, str(e))
print_ = self.print_error if hasattr(self, 'print_error') else print_error
print_("Exception in", func.__name__, ":", e.__class__.__name__, repr(e))
try:
traceback.print_exc(file=sys.stderr)
except BaseException as e2:
self.print_error("aiosafe:traceback.print_exc raised: {}... original exc: {}".format(e2, e))
return f2
print_error("traceback.print_exc raised: {}...".format(e2))
raise
return wrapper
def ignore_exceptions(func):
"""Decorator to silently swallow all exceptions."""
assert asyncio.iscoroutinefunction(func), 'func needs to be a coroutine'
async def wrapper(*args, **kwargs):
try:
return await func(*args, **kwargs)
except BaseException as e:
pass
return wrapper
TxMinedStatus = NamedTuple("TxMinedStatus", [("height", int),
("conf", int),
@ -941,7 +948,7 @@ class NetworkJobOnDefaultServer(PrintError):
async def stop(self):
await self.group.cancel_remaining()
@aiosafe
@log_exceptions
async def _restart(self, *args):
interface = self.network.interface
if interface is None:

Loading…
Cancel
Save