crash reporter: add EarlyExceptionsQueue
`util.send_exception_to_crash_reporter` is now useful and can be transparently used even before the exception hook is set up.
This commit is contained in:
@@ -24,6 +24,7 @@ import json
|
||||
import locale
|
||||
import traceback
|
||||
import sys
|
||||
import queue
|
||||
|
||||
from .version import ELECTRUM_VERSION
|
||||
from . import constants
|
||||
@@ -131,6 +132,43 @@ class BaseCrashReporter(Logger):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class EarlyExceptionsQueue:
|
||||
"""Helper singleton for explicitly sending exceptions to crash reporter.
|
||||
|
||||
Typically the GUIs set up an "exception hook" that catches all otherwise
|
||||
uncaught exceptions (which unroll the stack of a thread completely).
|
||||
This class provides methods to report *any* exception, and queueing logic
|
||||
that delays processing until the exception hook is set up.
|
||||
"""
|
||||
|
||||
_is_exc_hook_ready = False
|
||||
_exc_queue = queue.Queue()
|
||||
|
||||
@classmethod
|
||||
def set_hook_as_ready(cls):
|
||||
if cls._is_exc_hook_ready:
|
||||
return
|
||||
cls._is_exc_hook_ready = True
|
||||
while cls._exc_queue.qsize() > 0:
|
||||
e = cls._exc_queue.get()
|
||||
cls._send_exception_to_crash_reporter(e)
|
||||
|
||||
@classmethod
|
||||
def send_exception_to_crash_reporter(cls, e: BaseException):
|
||||
if cls._is_exc_hook_ready:
|
||||
cls._send_exception_to_crash_reporter(e)
|
||||
else:
|
||||
cls._exc_queue.put(e)
|
||||
|
||||
@staticmethod
|
||||
def _send_exception_to_crash_reporter(e: BaseException):
|
||||
assert EarlyExceptionsQueue._is_exc_hook_ready
|
||||
sys.excepthook(type(e), e, e.__traceback__)
|
||||
|
||||
|
||||
send_exception_to_crash_reporter = EarlyExceptionsQueue.send_exception_to_crash_reporter
|
||||
|
||||
|
||||
def trigger_crash():
|
||||
# note: do not change the type of the exception, the message,
|
||||
# or the name of this method. All reports generated through this
|
||||
|
||||
Reference in New Issue
Block a user