Browse Source

daemon error-handling: fix traceback.format_exception() on old python

The new API for traceback.format_exception was only added in python 3.10 (91e93794d5).
master
SomberNight 2 years ago
parent
commit
0866581b2c
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 4
      electrum/daemon.py
  2. 8
      electrum/util.py
  3. 4
      tests/qt_util.py

4
electrum/daemon.py

@ -46,7 +46,7 @@ from .network import Network
from .util import (json_decode, to_bytes, to_string, profiler, standardize_path, constant_time_compare, InvalidPassword) from .util import (json_decode, to_bytes, to_string, profiler, standardize_path, constant_time_compare, InvalidPassword)
from .invoices import PR_PAID, PR_EXPIRED from .invoices import PR_PAID, PR_EXPIRED
from .util import log_exceptions, ignore_exceptions, randrange, OldTaskGroup, UserFacingException, JsonRPCError from .util import log_exceptions, ignore_exceptions, randrange, OldTaskGroup, UserFacingException, JsonRPCError
from .util import EventListener, event_listener from .util import EventListener, event_listener, traceback_format_exception
from .wallet import Wallet, Abstract_Wallet from .wallet import Wallet, Abstract_Wallet
from .storage import WalletStorage from .storage import WalletStorage
from .wallet_db import WalletDB, WalletRequiresSplit, WalletRequiresUpgrade, WalletUnfinished from .wallet_db import WalletDB, WalletRequiresSplit, WalletRequiresUpgrade, WalletUnfinished
@ -264,7 +264,7 @@ class AuthenticatedServer(Logger):
'message': "internal error while executing RPC", 'message': "internal error while executing RPC",
'data': { 'data': {
"exception": repr(e), "exception": repr(e),
"traceback": "".join(traceback.format_exception(e)), "traceback": "".join(traceback_format_exception(e)),
}, },
} }
return web.json_response(response) return web.json_response(response)

8
electrum/util.py

@ -2064,6 +2064,14 @@ class nullcontext:
pass pass
def traceback_format_exception(exc: BaseException) -> Sequence[str]:
"""Compatibility wrapper for stdlib traceback.format_exception using python 3.10+ API."""
if sys.version_info[:3] >= (3, 10):
return traceback.format_exception(exc)
else:
return traceback.format_exception(type(exc), value=exc, tb=exc.__traceback__)
class classproperty(property): class classproperty(property):
"""~read-only class-level @property """~read-only class-level @property
from https://stackoverflow.com/a/13624858 by denis-ryzhkov from https://stackoverflow.com/a/13624858 by denis-ryzhkov

4
tests/qt_util.py

@ -6,6 +6,8 @@ from unittest import SkipTest
from PyQt6.QtCore import QCoreApplication, QMetaObject, Qt, pyqtSlot, QObject from PyQt6.QtCore import QCoreApplication, QMetaObject, Qt, pyqtSlot, QObject
from electrum.util import traceback_format_exception
class TestQCoreApplication(QCoreApplication): class TestQCoreApplication(QCoreApplication):
@pyqtSlot() @pyqtSlot()
@ -76,7 +78,7 @@ def qt_test(func):
if not res: if not res:
self._e = Exception('testcase timed out') self._e = Exception('testcase timed out')
if self._e: if self._e:
print("".join(traceback.format_exception(self._e))) print("".join(traceback_format_exception(self._e)))
# deallocate stored exception from qt thread otherwise we SEGV garbage collector # deallocate stored exception from qt thread otherwise we SEGV garbage collector
# instead, re-create using the exception message, special casing AssertionError and SkipTest # instead, re-create using the exception message, special casing AssertionError and SkipTest
e = None e = None

Loading…
Cancel
Save