h
This commit is contained in:
@@ -17,6 +17,8 @@ from Store.registry import _discover_store_classes, _required_keys_for
|
||||
from ProviderCore.registry import list_providers
|
||||
from TUI.modalscreen.matrix_room_picker import MatrixRoomPicker
|
||||
from TUI.modalscreen.selection_modal import SelectionModal
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ConfigModal(ModalScreen):
|
||||
"""A modal for editing the configuration."""
|
||||
@@ -187,22 +189,23 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.query_one("#add-tool-btn", Button).display = False
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to hide add-tool button in ConfigModal.on_mount")
|
||||
# Update DB path and last-saved on mount
|
||||
try:
|
||||
self.query_one("#config-db-path", Static).update(self._db_path)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update config DB path display in ConfigModal.on_mount")
|
||||
try:
|
||||
mtime = None
|
||||
try:
|
||||
mtime = db.db_path.stat().st_mtime
|
||||
mtime = __import__('datetime').datetime.utcfromtimestamp(mtime).isoformat() + "Z"
|
||||
except Exception:
|
||||
logger.exception("Failed to stat DB path for last-saved time")
|
||||
mtime = None
|
||||
self.query_one("#config-last-save", Static).update(f"Last saved: {mtime or '(unknown)'}")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update last-saved display in ConfigModal.on_mount")
|
||||
self.refresh_view()
|
||||
|
||||
def refresh_view(self) -> None:
|
||||
@@ -236,7 +239,7 @@ class ConfigModal(ModalScreen):
|
||||
self.query_one("#back-btn", Button).display = (self.editing_item_name is not None)
|
||||
self.query_one("#save-btn", Button).display = (self.editing_item_name is not None or self.current_category == "globals")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update visibility of config modal action buttons")
|
||||
|
||||
render_id = self._render_id
|
||||
|
||||
@@ -445,7 +448,7 @@ class ConfigModal(ModalScreen):
|
||||
if k:
|
||||
provider_schema_map[k.upper()] = field_def
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to retrieve provider config_schema")
|
||||
# Fetch Tool schema
|
||||
if item_type == "tool":
|
||||
try:
|
||||
@@ -457,7 +460,7 @@ class ConfigModal(ModalScreen):
|
||||
if k:
|
||||
provider_schema_map[k.upper()] = field_def
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to retrieve tool config_schema")
|
||||
|
||||
# Use columns for better layout of inputs with paste buttons
|
||||
container.mount(Label("Edit Settings"))
|
||||
@@ -629,7 +632,7 @@ class ConfigModal(ModalScreen):
|
||||
row.mount(Button("Paste", id=f"paste-{inp_id}", classes="paste-btn"))
|
||||
idx += 1
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to build required config inputs for provider/tool")
|
||||
|
||||
if (
|
||||
item_type == "provider"
|
||||
@@ -700,15 +703,16 @@ class ConfigModal(ModalScreen):
|
||||
seen_ids.add(rid)
|
||||
deduped.append(r)
|
||||
except Exception:
|
||||
logger.exception("Failed to process a matrix room entry while deduplicating")
|
||||
continue
|
||||
|
||||
if self._matrix_inline_list is not None and deduped:
|
||||
try:
|
||||
self._render_matrix_rooms_inline(deduped)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to render matrix inline rooms")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to fetch or process matrix rooms for inline rendering")
|
||||
except Exception:
|
||||
self._matrix_inline_checkbox_map = {}
|
||||
self._matrix_inline_list = None
|
||||
@@ -785,7 +789,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.config_data = reload_config()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to reload config after save conflict")
|
||||
self._editor_snapshot = None
|
||||
self.editing_item_name = None
|
||||
self.editing_item_type = None
|
||||
@@ -807,7 +811,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.config_data = reload_config()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to reload config after durable save")
|
||||
|
||||
if saved == 0:
|
||||
msg = f"Configuration saved (no rows changed) to {db.db_path.name}"
|
||||
@@ -816,7 +820,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.notify(msg, timeout=6)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to show notification message in ConfigModal")
|
||||
|
||||
# Return to the main list view within the current category
|
||||
self.editing_item_name = None
|
||||
@@ -828,7 +832,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
log(f"Durable save failed: {exc}")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to call log() for durable save error")
|
||||
elif bid in self._button_id_map:
|
||||
action, itype, name = self._button_id_map[bid]
|
||||
if action == "edit":
|
||||
@@ -870,7 +874,7 @@ class ConfigModal(ModalScreen):
|
||||
if cls.config_schema():
|
||||
options.append(stype)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to inspect store class config_schema for '%s'", stype)
|
||||
self.app.push_screen(SelectionModal("Select Store Type", options), callback=self.on_store_type_selected)
|
||||
elif bid == "add-provider-btn":
|
||||
provider_names = list(list_providers().keys())
|
||||
@@ -883,7 +887,7 @@ class ConfigModal(ModalScreen):
|
||||
if pcls.config_schema():
|
||||
options.append(ptype)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to inspect provider class config_schema for '%s'", ptype)
|
||||
self.app.push_screen(SelectionModal("Select Provider Type", options), callback=self.on_provider_type_selected)
|
||||
elif bid == "add-tool-btn":
|
||||
# Discover tool modules that advertise a config_schema()
|
||||
@@ -918,22 +922,22 @@ class ConfigModal(ModalScreen):
|
||||
cb = self.query_one(f"#{checkbox_id}", Checkbox)
|
||||
cb.value = True
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set matrix inline checkbox to True for '%s'", checkbox_id)
|
||||
try:
|
||||
self.query_one("#matrix-inline-save", Button).disabled = False
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to enable matrix inline save button")
|
||||
elif bid == "matrix-inline-clear":
|
||||
for checkbox_id in list(self._matrix_inline_checkbox_map.keys()):
|
||||
try:
|
||||
cb = self.query_one(f"#{checkbox_id}", Checkbox)
|
||||
cb.value = False
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set matrix inline checkbox to False for '%s'", checkbox_id)
|
||||
try:
|
||||
self.query_one("#matrix-inline-save", Button).disabled = True
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to disable matrix inline save button")
|
||||
elif bid == "matrix-inline-save":
|
||||
selected: List[str] = []
|
||||
for checkbox_id, room_id in self._matrix_inline_checkbox_map.items():
|
||||
@@ -942,7 +946,7 @@ class ConfigModal(ModalScreen):
|
||||
if cb.value and room_id:
|
||||
selected.append(room_id)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to read matrix inline checkbox '%s'", checkbox_id)
|
||||
if not selected:
|
||||
if self._matrix_status:
|
||||
self._matrix_status.update("No default rooms were saved.")
|
||||
@@ -963,7 +967,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.query_one("#matrix-inline-save", Button).disabled = True
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to disable matrix inline save button")
|
||||
self.refresh_view()
|
||||
|
||||
|
||||
@@ -1096,7 +1100,7 @@ class ConfigModal(ModalScreen):
|
||||
if key:
|
||||
new_config[key] = field_def.get("default", "")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to load config_schema for tool '%s'", tname)
|
||||
self.config_data["tool"][tname] = new_config
|
||||
|
||||
self.editing_item_type = "tool"
|
||||
@@ -1247,7 +1251,7 @@ class ConfigModal(ModalScreen):
|
||||
self._matrix_status.update("Matrix test skipped: please set both 'homeserver' and 'access_token' before testing.")
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to check matrix configuration before testing")
|
||||
|
||||
if self._matrix_status:
|
||||
self._matrix_status.update("Saving configuration before testing…")
|
||||
@@ -1280,7 +1284,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
debug(f"[matrix] Test connection failed: {exc}\n{tb}")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to debug matrix test failure")
|
||||
|
||||
msg = str(exc) or "Matrix test failed"
|
||||
m_lower = msg.lower()
|
||||
@@ -1328,7 +1332,7 @@ class ConfigModal(ModalScreen):
|
||||
if isinstance(parsed, (list, tuple, dict)):
|
||||
return self._normalize_cached_raw(parsed if isinstance(parsed, (list, tuple)) else [parsed])
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to parse cached_rooms JSON for provider matrix")
|
||||
|
||||
# Try Python literal eval (accepts single quotes, repr-style lists)
|
||||
try:
|
||||
@@ -1338,7 +1342,7 @@ class ConfigModal(ModalScreen):
|
||||
if isinstance(parsed, (list, tuple, dict)):
|
||||
return self._normalize_cached_raw(parsed if isinstance(parsed, (list, tuple)) else [parsed])
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to parse cached_rooms as Python literal for provider matrix")
|
||||
|
||||
# Try to extract dict-like pairs for room_id/name when the string looks like
|
||||
# a Python repr or partial dict fragment (e.g., "'room_id': '!r1', 'name': 'Room'"
|
||||
@@ -1362,11 +1366,11 @@ class ConfigModal(ModalScreen):
|
||||
if ids:
|
||||
return [{"room_id": rid, "name": ""} for rid in ids]
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to extract cached_rooms pairs or ids for provider matrix")
|
||||
|
||||
return []
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to parse cached_rooms for provider matrix")
|
||||
return []
|
||||
|
||||
def _normalize_cached_raw(self, parsed: List[Any]) -> List[Dict[str, Any]]:
|
||||
@@ -1383,6 +1387,7 @@ class ConfigModal(ModalScreen):
|
||||
if s:
|
||||
out.append({"room_id": s, "name": ""})
|
||||
except Exception:
|
||||
logger.exception("Failed to normalize cached_rooms entry: %r", it)
|
||||
continue
|
||||
return out
|
||||
|
||||
@@ -1406,7 +1411,7 @@ class ConfigModal(ModalScreen):
|
||||
self._matrix_status.update("Load skipped: please set both 'homeserver' and 'access_token' before loading rooms.")
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to check matrix configuration before load")
|
||||
|
||||
if self._matrix_status:
|
||||
self._matrix_status.update("Saving configuration before loading rooms…")
|
||||
@@ -1437,7 +1442,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
debug(f"[matrix] Load rooms failed: {exc}\n{tb}")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to debug matrix load failure")
|
||||
msg = str(exc) or "Matrix load failed"
|
||||
if "auth" in msg.lower():
|
||||
msg = msg + ". Please verify your access token and try again."
|
||||
@@ -1453,14 +1458,14 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.notify(full_msg, severity="error", timeout=8)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to show Matrix load failure notification")
|
||||
return
|
||||
|
||||
# Populate inline list
|
||||
try:
|
||||
self._render_matrix_rooms_inline(rooms)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to render inline matrix rooms")
|
||||
|
||||
# Persist cached rooms so they are available on next editor open
|
||||
try:
|
||||
@@ -1474,15 +1479,15 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
save_config(self.config_data)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to persist cached matrix rooms via save_config() fallback")
|
||||
if self._matrix_status:
|
||||
self._matrix_status.update(f"Loaded and cached {len(rooms)} room(s).")
|
||||
try:
|
||||
self.notify(f"Loaded {len(rooms)} rooms and cached the results", timeout=5)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to notify loaded-and-cached message for Matrix rooms")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to cache Matrix rooms after load")
|
||||
|
||||
def _open_matrix_room_picker(
|
||||
self,
|
||||
@@ -1522,15 +1527,15 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
save_config(self.config_data)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to persist cached matrix rooms via save_config() fallback")
|
||||
if self._matrix_status:
|
||||
self._matrix_status.update(f"Loaded {len(rooms)} rooms (cached)")
|
||||
try:
|
||||
self.notify(f"Loaded {len(rooms)} rooms and cached the results", timeout=5)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to notify loaded-and-cached message for Matrix rooms")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to cache Matrix rooms when inline view unavailable")
|
||||
return
|
||||
|
||||
# Clear current entries
|
||||
@@ -1549,7 +1554,7 @@ class ConfigModal(ModalScreen):
|
||||
save_btn = self.query_one("#matrix-inline-save", Button)
|
||||
save_btn.disabled = True
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to disable matrix inline save button when no rooms returned")
|
||||
return
|
||||
|
||||
any_selected = False
|
||||
@@ -1597,7 +1602,7 @@ class ConfigModal(ModalScreen):
|
||||
save_btn = self.query_one("#matrix-inline-save", Button)
|
||||
save_btn.disabled = not any_selected
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set matrix inline save button disabled state")
|
||||
|
||||
def _resolve_matrix_rooms_by_ids(self, ids: Iterable[str]) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
@@ -1628,7 +1633,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
debug(f"[config] failed to resolve matrix room names: {exc}")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to debug matrix name resolution")
|
||||
return []
|
||||
|
||||
def on_matrix_rooms_selected(self, result: Any = None) -> None:
|
||||
@@ -1683,7 +1688,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.query_one("#matrix-inline-save", Button).disabled = not any_selected
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update matrix inline save button")
|
||||
|
||||
def on_input_changed(self, event: Input.Changed) -> None:
|
||||
if event.input.id:
|
||||
@@ -1722,11 +1727,11 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.query_one("#config-db-path", Static).update(self._db_path)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update config db path label")
|
||||
try:
|
||||
self.query_one("#config-last-save", Static).update("Last saved: (saving...)")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update config last-save label")
|
||||
|
||||
log(f"ConfigModal scheduled save (changed={changed})")
|
||||
return changed
|
||||
@@ -1775,7 +1780,7 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.config_data = reload_config()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to reload config after save completion")
|
||||
|
||||
# Update last-saved label with file timestamp for visibility
|
||||
db_mtime = None
|
||||
@@ -1794,19 +1799,19 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.query_one("#config-last-save", Static).update(label_text)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to update last-save label with timestamp")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to compute last-save label text")
|
||||
|
||||
try:
|
||||
self.refresh_view()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to refresh config editor view after save completion")
|
||||
|
||||
try:
|
||||
self.notify(f"Configuration saved ({changed} change(s)) to {db.db_path.name}", timeout=5)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to show configuration saved notification")
|
||||
else:
|
||||
# No TUI available; log instead of updating UI
|
||||
log(f"Configuration saved ({changed} change(s)) to {db.db_path.name}")
|
||||
@@ -1818,17 +1823,17 @@ class ConfigModal(ModalScreen):
|
||||
try:
|
||||
self.notify(f"Save failed: {error}", severity="error", timeout=10)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to show save failed notification")
|
||||
|
||||
try:
|
||||
self.config_data = reload_config()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to reload config after save failure")
|
||||
|
||||
try:
|
||||
self.refresh_view()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to refresh view after save failure")
|
||||
else:
|
||||
log(f"Save failed: {error}")
|
||||
|
||||
@@ -1867,7 +1872,7 @@ class ConfigModal(ModalScreen):
|
||||
if rk not in required_keys:
|
||||
required_keys.append(rk)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to inspect provider class '%s' for required keys", item_name)
|
||||
section = self.config_data.get("provider", {}).get(item_name, {})
|
||||
elif item_type == "tool":
|
||||
try:
|
||||
@@ -1880,7 +1885,7 @@ class ConfigModal(ModalScreen):
|
||||
if k and k not in required_keys:
|
||||
required_keys.append(k)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to inspect tool module 'tool.%s' for required keys", item_name)
|
||||
section = self.config_data.get("tool", {}).get(item_name, {})
|
||||
|
||||
# Check required keys
|
||||
|
||||
@@ -630,7 +630,7 @@ class DownloadModal(ModalScreen):
|
||||
f"Download failed: {error_reason}",
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to finish worker during download failure handling")
|
||||
|
||||
# Also append detailed error info to worker stdout for visibility
|
||||
if worker:
|
||||
@@ -799,7 +799,7 @@ class DownloadModal(ModalScreen):
|
||||
f"Download error: {str(e)}",
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to finish worker during download error handling")
|
||||
self.app.call_from_thread(self._hide_progress)
|
||||
self.app.call_from_thread(self.dismiss)
|
||||
return
|
||||
@@ -1091,7 +1091,7 @@ class DownloadModal(ModalScreen):
|
||||
try:
|
||||
worker.finish("error", f"Download failed: {str(e)}")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to finish worker on download submit error")
|
||||
self.app.call_from_thread(self._hide_progress)
|
||||
self.app.call_from_thread(
|
||||
self.app.notify,
|
||||
|
||||
@@ -8,6 +8,8 @@ from textual.screen import ModalScreen
|
||||
from textual.widgets import Static, Button, Checkbox, ListView, ListItem
|
||||
from textual import work
|
||||
from rich.text import Text
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MatrixRoomPicker(ModalScreen[List[str]]):
|
||||
@@ -121,7 +123,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
|
||||
# Stop propagation so parent handlers (ConfigModal) don't react.
|
||||
event.stop()
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to stop ListView.Selected event propagation")
|
||||
|
||||
def _set_status(self, text: str) -> None:
|
||||
if self._status_widget:
|
||||
@@ -137,6 +139,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
|
||||
any_selected = True
|
||||
break
|
||||
except Exception:
|
||||
logger.exception("Error querying checkbox in MatrixRoomPicker; skipping")
|
||||
continue
|
||||
if self._save_button:
|
||||
self._save_button.disabled = not any_selected
|
||||
@@ -214,7 +217,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
|
||||
cb = self.query_one(f"#{checkbox_id}", Checkbox)
|
||||
cb.value = True
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set checkbox value in MatrixRoomPicker")
|
||||
if self._save_button:
|
||||
self._save_button.disabled = False
|
||||
elif event.button.id == "matrix-room-clear":
|
||||
@@ -223,7 +226,7 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
|
||||
cb = self.query_one(f"#{checkbox_id}", Checkbox)
|
||||
cb.value = False
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set checkbox value to False in MatrixRoomPicker")
|
||||
if self._save_button:
|
||||
self._save_button.disabled = True
|
||||
elif event.button.id == "matrix-room-save":
|
||||
@@ -234,5 +237,5 @@ class MatrixRoomPicker(ModalScreen[List[str]]):
|
||||
if cb.value and room_id:
|
||||
selected.append(room_id)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to read checkbox state for '%s' while saving MatrixRoomPicker selection", checkbox_id)
|
||||
self.dismiss(selected)
|
||||
|
||||
@@ -501,7 +501,7 @@ class WorkersModal(ModalScreen):
|
||||
try:
|
||||
self.stdout_display.cursor_location = (len(combined_text) - 1, 0)
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("Failed to set stdout_display cursor location")
|
||||
logger.info("[workers-modal] Updated stdout display successfully")
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
|
||||
Reference in New Issue
Block a user