Python exceptions can now be handled via QML

callCoro/callBackendCoro can now take onSuccess(result) and
onError(type, args, errorObject) callbacks.
This commit is contained in:
miruka 2019-10-28 06:26:02 -04:00
parent fe4eff62c5
commit 5894481dc5
4 changed files with 35 additions and 12 deletions

View File

@ -61,9 +61,17 @@ class App:
def _call_coro(self, coro: Coroutine, uuid: str) -> None: def _call_coro(self, coro: Coroutine, uuid: str) -> None:
self.run_in_loop(coro).add_done_callback( def on_done(future: Future) -> None:
lambda future: CoroutineDone(uuid=uuid, result=future.result()), try:
) result = future.result()
exception = None
except Exception as err:
result = None
exception = err
CoroutineDone(uuid, result, exception)
self.run_in_loop(coro).add_done_callback(on_done)
def call_backend_coro(self, name: str, uuid: str, args: Sequence[str] = (), def call_backend_coro(self, name: str, uuid: str, args: Sequence[str] = (),

View File

@ -1,6 +1,6 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
from typing import Any, Dict, List, Union from typing import Any, Dict, List, Optional, Union
import pyotherside import pyotherside
@ -47,8 +47,9 @@ class AlertRequested(PyOtherSideEvent):
class CoroutineDone(PyOtherSideEvent): class CoroutineDone(PyOtherSideEvent):
"""Indicate that an asyncio coroutine finished.""" """Indicate that an asyncio coroutine finished."""
uuid: str = field() uuid: str = field()
result: Any = None result: Any = None
exception: Optional[Exception] = None
@dataclass @dataclass

View File

@ -14,18 +14,20 @@ Python {
return call_sync("APP.backend." + name, args) return call_sync("APP.backend." + name, args)
} }
function callCoro(name, args=[], callback=null) { function callCoro(name, args=[], onSuccess=null, onError=null) {
let uuid = Math.random() + "." + name let uuid = Math.random() + "." + name
pendingCoroutines[uuid] = callback || function() {} pendingCoroutines[uuid] = {onSuccess, onError}
call("APP.call_backend_coro", [name, uuid, args]) call("APP.call_backend_coro", [name, uuid, args])
} }
function callClientCoro(accountId, name, args=[], callback=null) { function callClientCoro(
accountId, name, args=[], onSuccess=null, onError=null
) {
callCoro("wait_until_client_exists", [accountId], () => { callCoro("wait_until_client_exists", [accountId], () => {
let uuid = Math.random() + "." + name let uuid = Math.random() + "." + name
pendingCoroutines[uuid] = callback || function() {} pendingCoroutines[uuid] = {onSuccess, onError}
call("APP.call_client_coro", [accountId, name, uuid, args]) call("APP.call_client_coro", [accountId, name, uuid, args])
}) })
} }

View File

@ -13,8 +13,20 @@ function onAlertRequested() {
} }
function onCoroutineDone(uuid, result) { function onCoroutineDone(uuid, result, error) {
py.pendingCoroutines[uuid](result) let onSuccess = py.pendingCoroutines[uuid].onSuccess
let onError = py.pendingCoroutines[uuid].onError
if (error) {
let type = py.getattr(py.getattr(error, "__class__"), "__name__")
let args = py.getattr(error, "args")
onError ?
onError(type, args, error) :
console.error(uuid + ": " + type + ": " + args)
} else if (onSuccess) { onSuccess(result) }
delete pendingCoroutines[uuid] delete pendingCoroutines[uuid]
} }