mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-07 05:40:17 +00:00
Improve Displaying Error to User on Khoj window in Desktop GUI
- Show a helpful error message in the GUI to the user, instead of the crashing if loading config fails, for e.g if file wasn't found - Collate GUI errors into an ErrorType enum class - Remove previous error messages before showing the new one
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
# Standard Packages
|
# Standard Packages
|
||||||
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
import webbrowser
|
import webbrowser
|
||||||
@@ -152,6 +153,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
def add_error_message(self, message: str):
|
def add_error_message(self, message: str):
|
||||||
"Add Error Message to Configure Screen"
|
"Add Error Message to Configure Screen"
|
||||||
|
# Remove any existing error messages
|
||||||
|
for message_prefix in ErrorType:
|
||||||
|
for i in reversed(range(self.layout.count())):
|
||||||
|
current_widget = self.layout.itemAt(i).widget()
|
||||||
|
if isinstance(current_widget, QtWidgets.QLabel) and current_widget.text().startswith(message_prefix.value):
|
||||||
|
self.layout.removeWidget(current_widget)
|
||||||
|
current_widget.deleteLater()
|
||||||
|
|
||||||
|
# Add new error message
|
||||||
|
if message:
|
||||||
error_message = QtWidgets.QLabel()
|
error_message = QtWidgets.QLabel()
|
||||||
error_message.setWordWrap(True)
|
error_message.setWordWrap(True)
|
||||||
error_message.setText(message)
|
error_message.setText(message)
|
||||||
@@ -196,22 +207,17 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
self.new_config['processor'][child.processor_type.value]['openai-api-key'] = child.input_field.toPlainText() if child.input_field.toPlainText() != '' else None
|
self.new_config['processor'][child.processor_type.value]['openai-api-key'] = child.input_field.toPlainText() if child.input_field.toPlainText() != '' else None
|
||||||
|
|
||||||
def save_settings_to_file(self) -> bool:
|
def save_settings_to_file(self) -> bool:
|
||||||
|
"Save validated settings to file"
|
||||||
# Validate config before writing to file
|
# Validate config before writing to file
|
||||||
try:
|
try:
|
||||||
yaml_utils.parse_config_from_string(self.new_config)
|
yaml_utils.parse_config_from_string(self.new_config)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error validating config: {e}")
|
print(f"Error validating config: {e}")
|
||||||
self.add_error_message(f"Error validating config: {e}")
|
self.add_error_message(f"{ErrorType.ConfigValidationError.value}: {e}")
|
||||||
return False
|
return False
|
||||||
else:
|
|
||||||
# Remove error message if present
|
|
||||||
for i in range(self.layout.count()):
|
|
||||||
current_widget = self.layout.itemAt(i).widget()
|
|
||||||
if isinstance(current_widget, QtWidgets.QLabel) and current_widget.text().startswith("Error validating config:"):
|
|
||||||
self.layout.removeWidget(current_widget)
|
|
||||||
current_widget.deleteLater()
|
|
||||||
|
|
||||||
# Save the config to app config file
|
# Save the config to app config file
|
||||||
|
self.add_error_message(None)
|
||||||
yaml_utils.save_config_to_file(self.new_config, self.config_file)
|
yaml_utils.save_config_to_file(self.new_config, self.config_file)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -238,6 +244,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
self.thread.started.connect(self.settings_loader.run)
|
self.thread.started.connect(self.settings_loader.run)
|
||||||
self.settings_loader.finished.connect(self.thread.quit)
|
self.settings_loader.finished.connect(self.thread.quit)
|
||||||
self.settings_loader.finished.connect(self.settings_loader.deleteLater)
|
self.settings_loader.finished.connect(self.settings_loader.deleteLater)
|
||||||
|
self.settings_loader.error.connect(self.add_error_message)
|
||||||
self.thread.finished.connect(self.thread.deleteLater)
|
self.thread.finished.connect(self.thread.deleteLater)
|
||||||
|
|
||||||
# Start thread
|
# Start thread
|
||||||
@@ -257,6 +264,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
class SettingsLoader(QObject):
|
class SettingsLoader(QObject):
|
||||||
"Load Settings Thread"
|
"Load Settings Thread"
|
||||||
finished = pyqtSignal()
|
finished = pyqtSignal()
|
||||||
|
error = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, load_settings_func):
|
def __init__(self, load_settings_func):
|
||||||
super(SettingsLoader, self).__init__()
|
super(SettingsLoader, self).__init__()
|
||||||
@@ -264,7 +272,12 @@ class SettingsLoader(QObject):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"Load Settings"
|
"Load Settings"
|
||||||
|
try:
|
||||||
self.load_settings_func()
|
self.load_settings_func()
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
self.error.emit(f"{ErrorType.ConfigLoadingError.value}: {e}")
|
||||||
|
else:
|
||||||
|
self.error.emit(None)
|
||||||
self.finished.emit()
|
self.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
@@ -278,3 +291,8 @@ class ProcessorCheckBox(QtWidgets.QCheckBox):
|
|||||||
def __init__(self, text, processor_type: ProcessorType, parent=None):
|
def __init__(self, text, processor_type: ProcessorType, parent=None):
|
||||||
self.processor_type = processor_type
|
self.processor_type = processor_type
|
||||||
super(ProcessorCheckBox, self).__init__(text, parent=parent)
|
super(ProcessorCheckBox, self).__init__(text, parent=parent)
|
||||||
|
|
||||||
|
class ErrorType(Enum):
|
||||||
|
"Error Types"
|
||||||
|
ConfigLoadingError = "Config Loading Error"
|
||||||
|
ConfigValidationError = "Config Validation Error"
|
||||||
|
|||||||
Reference in New Issue
Block a user