GUI popup for uncaught asyncio loop exceptions
This commit is contained in:
@@ -49,6 +49,15 @@ class CoroutineDone(PyOtherSideEvent):
|
||||
traceback: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class LoopException(PyOtherSideEvent):
|
||||
"""Indicate that an uncaught exception occured in the asyncio loop."""
|
||||
|
||||
message: str = field()
|
||||
exception: Optional[Exception] = field()
|
||||
traceback: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ModelUpdated(PyOtherSideEvent):
|
||||
"""Indicate that a backend `Model`'s data changed."""
|
||||
|
@@ -12,7 +12,7 @@ from threading import Thread
|
||||
from typing import Coroutine, Sequence
|
||||
|
||||
from .backend import Backend
|
||||
from .pyotherside_events import CoroutineDone
|
||||
from .pyotherside_events import CoroutineDone, LoopException
|
||||
|
||||
try:
|
||||
import uvloop
|
||||
@@ -39,9 +39,24 @@ class QMLBridge:
|
||||
self.backend: Backend = Backend()
|
||||
|
||||
self._loop = asyncio.get_event_loop()
|
||||
self._loop.set_exception_handler(self._loop_exception_handler)
|
||||
|
||||
Thread(target=self._start_asyncio_loop).start()
|
||||
|
||||
|
||||
def _loop_exception_handler(
|
||||
self, loop: asyncio.AbstractEventLoop, context: dict,
|
||||
) -> None:
|
||||
if "exception" in context:
|
||||
err = context["exception"]
|
||||
trace = "".join(
|
||||
traceback.format_exception(type(err), err, err.__traceback__),
|
||||
)
|
||||
LoopException(context["message"], err, trace)
|
||||
|
||||
loop.default_exception_handler(context)
|
||||
|
||||
|
||||
def _start_asyncio_loop(self) -> None:
|
||||
asyncio.set_event_loop(self._loop)
|
||||
self._loop.run_forever()
|
||||
|
Reference in New Issue
Block a user