1
0
mirror of https://github.com/bpozdena/OneDriveGUI.git synced 2026-10-24 04:59:17 +03:00

Improved error handling and messaging #255

This commit is contained in:
Boris Pozdena
2025-11-21 09:48:46 +01:00
parent 5256d9fbaa
commit 64c0e46276
4 changed files with 113 additions and 7 deletions

View File

@@ -400,6 +400,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.start_onedrive_monitor(profile_name)
def start_onedrive_monitor(self, profile_name, options=""):
# Clear any previous error messages when starting sync
self.profile_status_pages[profile_name].label_error_icon.clear()
self.profile_status_pages[profile_name].label_error_icon.setToolTip("")
if profile_name not in workers:
workers[profile_name] = WorkerThread(profile_name, options)
workers[profile_name].start()
@@ -497,6 +501,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.profile_status_pages[profile].label_free_space.setText(data["free_space"])
self.profile_status_pages[profile].label_account_type.setText(data["account_type"])
# Handle error message display
if "error_message" in data and data["error_message"]:
# Show error icon with full error message in tooltip
pixmap_warning = QPixmap(DIR_PATH + "/resources/images/warning.png").scaled(20, 20, Qt.KeepAspectRatio)
self.profile_status_pages[profile].label_error_icon.setPixmap(pixmap_warning)
self.profile_status_pages[profile].label_error_icon.setToolTip(data["error_message"])
else:
# Clear error icon
self.profile_status_pages[profile].label_error_icon.clear()
self.profile_status_pages[profile].label_error_icon.setToolTip("")
def event_update_progress(self, data, profile):
"""
data:

View File

@@ -300,6 +300,22 @@ QPushButton:pressed {background-color: rgba(0, 0, 0, 0.1)}</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_error_icon">
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QToolTip { color: white; }</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">

View File

@@ -3,7 +3,7 @@
################################################################################
## Form generated from reading UI file 'process_status_page.ui'
##
## Created by: Qt User Interface Compiler version 6.2.2
## Created by: Qt User Interface Compiler version 6.10.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
@@ -54,7 +54,7 @@ class Ui_status_page(object):
self.horizontalLayout_3.addWidget(self.pushButton_quit)
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout_3.addItem(self.horizontalSpacer)
@@ -130,7 +130,14 @@ class Ui_status_page(object):
self.horizontalLayout_2.addWidget(self.label_version_check)
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.label_error_icon = QLabel(self.frame)
self.label_error_icon.setObjectName(u"label_error_icon")
self.label_error_icon.setMaximumSize(QSize(20, 16777215))
self.label_error_icon.setStyleSheet(u"QToolTip { color: white; }")
self.horizontalLayout_2.addWidget(self.label_error_icon)
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout_2.addItem(self.horizontalSpacer_2)
@@ -202,7 +209,7 @@ class Ui_status_page(object):
self.horizontalLayout.setContentsMargins(-1, 6, -1, 6)
self.pushButton_open_dir = QPushButton(status_page)
self.pushButton_open_dir.setObjectName(u"pushButton_open_dir")
sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
sizePolicy = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_open_dir.sizePolicy().hasHeightForWidth())
@@ -264,6 +271,7 @@ class Ui_status_page(object):
#endif // QT_CONFIG(tooltip)
self.pushButton_stop.setText(QCoreApplication.translate("status_page", u"Stop", None))
self.label_version_check.setText("")
self.label_error_icon.setText("")
#if QT_CONFIG(tooltip)
self.label_free_space.setToolTip(QCoreApplication.translate("status_page", u"Free Space", None))
#endif // QT_CONFIG(tooltip)

View File

@@ -92,6 +92,9 @@ class WorkerThread(QThread):
"account_type": "",
}
# Track pending error for multi-line error messages
self.pending_error = None
self.profile_status["status_message"] = "OneDrive sync is starting..."
self.update_profile_status.emit(self.profile_status, self.profile_name)
@@ -119,11 +122,54 @@ class WorkerThread(QThread):
if time.time() > timeout:
break
def _emit_error_status(self, full_error_message):
"""Format and emit error message with truncation and line splitting."""
# Format for status message: max 50 chars per line, up to 3 lines (150 chars total)
max_chars_per_line = 50
max_lines = 3
max_total_chars = max_chars_per_line * max_lines
if len(full_error_message) > max_total_chars:
# Truncate to 150 chars total
display_text = full_error_message[: max_total_chars - 3] + "..."
else:
display_text = full_error_message
# Split into lines of max 50 characters
lines = []
words = display_text.split()
current_line = ""
for word in words:
if len(current_line) + len(word) + 1 <= max_chars_per_line:
current_line += word + " "
else:
if current_line:
lines.append(current_line.strip())
current_line = word + " "
if len(lines) >= max_lines:
break
if current_line and len(lines) < max_lines:
lines.append(current_line.strip())
truncated_error = "\n".join(lines)
self.profile_status["status_message"] = f"Error: {truncated_error}"
self.profile_status["error_message"] = full_error_message # Full error for tooltip
self.update_profile_status.emit(self.profile_status, self.profile_name)
def read_stdout(self):
stdout = self.onedrive_process.stdout.readline().strip()
if stdout != "":
logging.info(f"[{self.profile_name}] " + stdout)
# Check if we have a pending error from previous line that wasn't followed by "Error Message:"
if self.pending_error and "Error Message:" not in stdout:
# Emit the pending error since the next line didn't continue it
self._emit_error_status(self.pending_error)
self.pending_error = None
if "Calling Function: testNetwork()" in stdout:
self.profile_status["status_message"] = "Cannot connect to Microsoft OneDrive Service"
self.update_profile_status.emit(self.profile_status, self.profile_name)
@@ -274,9 +320,9 @@ class WorkerThread(QThread):
self.profile_status["status_message"] = "Cannot connect to Microsoft OneDrive Service."
self.update_profile_status.emit(self.profile_status, self.profile_name)
elif "application is already running" in stdout:
self.profile_status["status_message"] = """OneDrive is already running outside OneDriveGUI!\nPlease stop it first."""
self.update_profile_status.emit(self.profile_status, self.profile_name)
# elif "application is already running" in stdout:
# self.profile_status["status_message"] = """OneDrive is already running outside OneDriveGUI!\nPlease stop it first."""
# self.update_profile_status.emit(self.profile_status, self.profile_name)
elif "command not found" in stdout:
logging.error(
@@ -298,6 +344,27 @@ class WorkerThread(QThread):
self.update_profile_status.emit(self.profile_status, self.profile_name)
self.update_credentials.emit(self.profile_name)
elif "Error Message:" in stdout:
# Check if this is a continuation of a previous ERROR: line
if self.pending_error:
error_parts = stdout.split("Error Message:", 1)
if len(error_parts) > 1:
additional_error = error_parts[1].strip()
# Combine with pending error
full_error_message = f"{self.pending_error} {additional_error}"
else:
full_error_message = self.pending_error
self.pending_error = None # Clear pending error
self._emit_error_status(full_error_message)
elif "ERROR:" in stdout:
# Extract error message after "ERROR:" prefix
error_parts = stdout.split("ERROR:", 1)
if len(error_parts) > 1:
error_text = error_parts[1].strip()
# Store as pending error to check if next line has "Error Message:"
self.pending_error = error_text
else:
# logging.debug(f"No rule matched: {stdout}")
pass