0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 11:41:49 +02:00

fix: do not display error popup if command is executed via RPC

This commit is contained in:
2024-12-20 13:13:05 +01:00
committed by wakonig_k
parent c405421db9
commit 52c5286d64
3 changed files with 51 additions and 15 deletions

View File

@ -1,9 +1,11 @@
from __future__ import annotations from __future__ import annotations
import functools
import json import json
import signal import signal
import sys import sys
from contextlib import redirect_stderr, redirect_stdout import types
from contextlib import contextmanager, redirect_stderr, redirect_stdout
from typing import Union from typing import Union
from bec_lib.endpoints import MessageEndpoints from bec_lib.endpoints import MessageEndpoints
@ -13,6 +15,7 @@ from bec_lib.utils.import_utils import lazy_import
from qtpy.QtCore import Qt, QTimer from qtpy.QtCore import Qt, QTimer
from bec_widgets.cli.rpc.rpc_register import RPCRegister from bec_widgets.cli.rpc.rpc_register import RPCRegister
from bec_widgets.qt_utils.error_popups import ErrorPopupUtility
from bec_widgets.utils import BECDispatcher from bec_widgets.utils import BECDispatcher
from bec_widgets.utils.bec_connector import BECConnector from bec_widgets.utils.bec_connector import BECConnector
from bec_widgets.widgets.containers.dock import BECDockArea from bec_widgets.widgets.containers.dock import BECDockArea
@ -23,6 +26,27 @@ messages = lazy_import("bec_lib.messages")
logger = bec_logger.logger logger = bec_logger.logger
@contextmanager
def rpc_exception_hook(err_func):
"""This context replaces the popup message box for error display with a specific hook"""
# get error popup utility singleton
popup = ErrorPopupUtility()
# save current setting
old_exception_hook = popup.custom_exception_hook
# install err_func, if it is a callable
def custom_exception_hook(self, exc_type, value, tb, **kwargs):
err_func({"error": popup.get_error_message(exc_type, value, tb)})
popup.custom_exception_hook = types.MethodType(custom_exception_hook, popup)
try:
yield popup
finally:
# restore state of error popup utility singleton
popup.custom_exception_hook = old_exception_hook
class BECWidgetsCLIServer: class BECWidgetsCLIServer:
def __init__( def __init__(
@ -57,6 +81,7 @@ class BECWidgetsCLIServer:
def on_rpc_update(self, msg: dict, metadata: dict): def on_rpc_update(self, msg: dict, metadata: dict):
request_id = metadata.get("request_id") request_id = metadata.get("request_id")
logger.debug(f"Received RPC instruction: {msg}, metadata: {metadata}") logger.debug(f"Received RPC instruction: {msg}, metadata: {metadata}")
with rpc_exception_hook(functools.partial(self.send_response, request_id, False)):
try: try:
obj = self.get_object_from_config(msg["parameter"]) obj = self.get_object_from_config(msg["parameter"])
method = msg["action"] method = msg["action"]

View File

@ -169,12 +169,14 @@ class _ErrorPopupUtility(QObject):
error_message = " ".join(captured_message) error_message = " ".join(captured_message)
return error_message return error_message
def get_error_message(self, exctype, value, tb):
return "".join(traceback.format_exception(exctype, value, tb))
def custom_exception_hook(self, exctype, value, tb, popup_error=False): def custom_exception_hook(self, exctype, value, tb, popup_error=False):
if popup_error or self.enable_error_popup: if popup_error or self.enable_error_popup:
error_message = traceback.format_exception(exctype, value, tb)
self.error_occurred.emit( self.error_occurred.emit(
"Method error" if popup_error else "Application Error", "Method error" if popup_error else "Application Error",
"".join(error_message), self.get_error_message(exctype, value, tb),
self.parent(), self.parent(),
) )
else: else:

View File

@ -349,3 +349,12 @@ def test_rpc_gui_obj(connected_client_gui_obj, qtbot):
# check it is really deleted on server # check it is really deleted on server
gui_info = gui._dump() gui_info = gui._dump()
assert yw._gui_id not in gui_info assert yw._gui_id not in gui_info
def test_rpc_call_with_exception_in_safeslot_error_popup(connected_client_gui_obj, qtbot):
gui = connected_client_gui_obj
gui.main.add_dock("test")
with pytest.raises(ValueError):
gui.main.add_dock("test")
# time.sleep(0.1)