Error handling for bad files

This commit is contained in:
dazedanon 2025-10-28 12:51:52 -05:00
parent 399447e3ac
commit 976f627332

View file

@ -59,6 +59,7 @@ class TranslationWorker(QThread):
log_signal = pyqtSignal(str) log_signal = pyqtSignal(str)
progress_signal = pyqtSignal(int, int, str) # current_file, total_files, filename progress_signal = pyqtSignal(int, int, str) # current_file, total_files, filename
item_progress_signal = pyqtSignal(str, int, int) # filename, current_item, total_items (for tqdm within file) item_progress_signal = pyqtSignal(str, int, int) # filename, current_item, total_items (for tqdm within file)
file_error_signal = pyqtSignal(str, str) # filename, error_message
finished_signal = pyqtSignal(bool, str) finished_signal = pyqtSignal(bool, str)
def __init__(self, project_root, module_info, estimate_only=False, selected_files=None, parse_speakers=False): def __init__(self, project_root, module_info, estimate_only=False, selected_files=None, parse_speakers=False):
@ -233,14 +234,31 @@ class TranslationWorker(QThread):
return result_text.encode('ascii', 'ignore').decode('ascii') return result_text.encode('ascii', 'ignore').decode('ascii')
return "Success" return "Success"
else: else:
# Extract error message from stderr
error_msg = stderr.strip() if stderr.strip() else "Unknown error" error_msg = stderr.strip() if stderr.strip() else "Unknown error"
# Handle potential Unicode errors in error messages # Handle potential Unicode errors in error messages
try: try:
clean_error = error_msg.encode('ascii', 'ignore').decode('ascii') clean_error = error_msg.encode('ascii', 'ignore').decode('ascii')
except: except:
clean_error = "Unicode encoding error in process output" clean_error = "Unicode encoding error in process output"
self.emit_log(f"❌ Process error: {clean_error}")
return "Fail" # Check if stderr contains the actual exception message
# Format from subprocess_runner.py: "ERROR:actual error message"
actual_error = clean_error
for line in clean_error.split('\n'):
if line.startswith('ERROR:'):
actual_error = line[6:] # Remove 'ERROR:' prefix
break
# Check for exception lines in traceback
if 'NameError:' in line or 'Error:' in line:
# Extract just the error message part
if ':' in line:
actual_error = line.split(':', 1)[1].strip()
break
self.emit_log(f"❌ Process error: {actual_error}")
# Return the actual error so it can be used to determine if file is unsupported
return ("SUBPROCESS_ERROR", actual_error)
except Exception as e: except Exception as e:
self.emit_log(f"❌ Failed to run module process: {str(e)}") self.emit_log(f"❌ Failed to run module process: {str(e)}")
@ -347,7 +365,12 @@ class TranslationWorker(QThread):
# Handler prints cost lines via tqdm.write; capture nothing here # Handler prints cost lines via tqdm.write; capture nothing here
except Exception as e: except Exception as e:
tb_line = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno) tb_line = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno)
self.emit_log(f"❌ Error processing {filename}: {str(e)} | Line: {tb_line}") error_msg = f"❌ Error processing {filename}: {str(e)} | Line: {tb_line}"
self.emit_log(error_msg)
# Emit file error signal to mark this file as failed
self.file_error_signal.emit(filename, str(e))
completed_count += 1
self.emit_progress(completed_count, total_files, filename)
# After all files processed, finalize speaker parse (translates collected speakers) # After all files processed, finalize speaker parse (translates collected speakers)
try: try:
@ -420,18 +443,27 @@ class TranslationWorker(QThread):
try: try:
result = future.result() result = future.result()
if result and result != "Fail" and result != "Stopped": # Check if result is an error tuple from subprocess
if isinstance(result, tuple) and len(result) == 2 and result[0] == "SUBPROCESS_ERROR":
error_message = result[1]
self.file_error_signal.emit(filename, error_message)
elif result and result != "Fail" and result != "Stopped":
total_cost = result total_cost = result
# Don't log completion here since the module already logged the detailed cost info # Don't log completion here since the module already logged the detailed cost info
elif result == "Stopped": elif result == "Stopped":
# Don't log here, already handled # Don't log here, already handled
break break
else: else:
self.emit_log(f"❌ Failed processing {filename}") error_msg = f"❌ Failed processing {filename}"
self.emit_log(error_msg)
# Emit file error signal to mark this file as failed
self.file_error_signal.emit(filename, "Translation failed")
except Exception as e: except Exception as e:
tb_line = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno) tb_line = str(traceback.extract_tb(sys.exc_info()[2])[-1].lineno)
error_msg = f"❌ Error processing {filename}: {str(e)} | Line: {tb_line}" error_msg = f"❌ Error processing {filename}: {str(e)} | Line: {tb_line}"
self.emit_log(error_msg) self.emit_log(error_msg)
# Emit file error signal to mark this file as failed
self.file_error_signal.emit(filename, str(e))
finally: finally:
# Properly shutdown the executor # Properly shutdown the executor
if self.executor: if self.executor:
@ -1349,8 +1381,8 @@ class TranslationTab(QWidget):
# Progress label (small) shown next to filename # Progress label (small) shown next to filename
progress_label = QLabel("Waiting...") progress_label = QLabel("Waiting...")
progress_label.setStyleSheet("color: #888888; font-size: 11px;") progress_label.setStyleSheet("color: #888888; font-size: 10px;")
progress_label.setFixedWidth(80) progress_label.setFixedWidth(110)
layout.addWidget(progress_label) layout.addWidget(progress_label)
# Progress bar (stretch to fill remaining space) # Progress bar (stretch to fill remaining space)
@ -1430,15 +1462,14 @@ class TranslationTab(QWidget):
item['label'].setText(f"{current}/{total}") item['label'].setText(f"{current}/{total}")
item['label'].setStyleSheet("color: #007acc; font-weight: bold;") item['label'].setStyleSheet("color: #007acc; font-weight: bold;")
def mark_file_complete(self, filename, success=True): def mark_file_complete(self, filename, success=True, error_message=None):
"""Mark a file as complete.""" """Mark a file as complete or failed."""
if filename in self.file_progress_items: if filename in self.file_progress_items:
item = self.file_progress_items[filename] item = self.file_progress_items[filename]
item['checkbox'].setChecked(True)
# If we have detailed result labels already set (via append_log), # If we have detailed result labels already set (via append_log),
# show them and hide the progress bar to make room. # show them and hide the progress bar to make room.
if success: if success:
# If tokens/cost/time were already filled by parse, they'll be visible. item['checkbox'].setChecked(True)
if item.get('tokens_label') and item['tokens_label'].text(): if item.get('tokens_label') and item['tokens_label'].text():
item['tokens_label'].setVisible(True) item['tokens_label'].setVisible(True)
item['cost_label'].setVisible(True) item['cost_label'].setVisible(True)
@ -1475,15 +1506,46 @@ class TranslationTab(QWidget):
except Exception: except Exception:
pass pass
else: else:
# Check if this is an unsupported file type error
is_unsupported = False
if error_message:
error_lower = error_message.lower()
is_unsupported = (
" not supported" in error_lower or
"not supported" == error_lower or
"unsupported" in error_lower or
"invalid file" in error_lower or
"wrong file type" in error_lower
)
# Mark as failed - checkbox unchecked, red X or warning icon
item['checkbox'].setChecked(False)
try: try:
item['status_label'].setText("") if is_unsupported:
item['status_label'].setStyleSheet("color: #f48771; font-weight: bold; font-size: 11px;") item['status_label'].setText("")
item['status_label'].setStyleSheet("color: #f1c40f; font-weight: bold; font-size: 13px;")
else:
item['status_label'].setText("")
item['status_label'].setStyleSheet("color: #f48771; font-weight: bold; font-size: 11px;")
item['status_label'].setVisible(True) item['status_label'].setVisible(True)
# Set tooltip with error message if provided
if error_message:
item['status_label'].setToolTip(f"Error: {error_message}")
item['widget'].setToolTip(f"Error: {error_message}")
except Exception: except Exception:
pass pass
try: try:
item['label'].setText("") if is_unsupported:
item['label'].setStyleSheet("color: #f48771; font-size: 11px;") item['label'].setText("Not Supported")
item['label'].setStyleSheet("color: #f1c40f; font-weight: bold; font-size: 10px;")
else:
item['label'].setText("Failed")
item['label'].setStyleSheet("color: #f48771; font-weight: bold; font-size: 10px;")
except Exception:
pass
try:
# Hide progress bar and show error state
item['progress_bar'].setVisible(False)
except Exception: except Exception:
pass pass
@ -1606,6 +1668,7 @@ class TranslationTab(QWidget):
self.translation_worker.log_signal.connect(self.append_log) self.translation_worker.log_signal.connect(self.append_log)
self.translation_worker.progress_signal.connect(self.update_file_progress) self.translation_worker.progress_signal.connect(self.update_file_progress)
self.translation_worker.item_progress_signal.connect(self.update_item_progress) self.translation_worker.item_progress_signal.connect(self.update_item_progress)
self.translation_worker.file_error_signal.connect(self.on_file_error)
self.translation_worker.finished_signal.connect(self.on_translation_finished) self.translation_worker.finished_signal.connect(self.on_translation_finished)
# Prepare a per-run log file in log/history and start tailing it so # Prepare a per-run log file in log/history and start tailing it so
# the right-hand log panel shows only this run's new lines. # the right-hand log panel shows only this run's new lines.
@ -1777,6 +1840,11 @@ class TranslationTab(QWidget):
if self.file_progress_items[filename]['label'].text() == "Waiting...": if self.file_progress_items[filename]['label'].text() == "Waiting...":
self.file_progress_items[filename]['label'].setText("Translating...") self.file_progress_items[filename]['label'].setText("Translating...")
self.file_progress_items[filename]['label'].setStyleSheet("color: #007acc; font-weight: bold;") self.file_progress_items[filename]['label'].setStyleSheet("color: #007acc; font-weight: bold;")
def on_file_error(self, filename, error_message):
"""Handle a file translation error."""
# Mark the file as failed with the error message
self.mark_file_complete(filename, success=False, error_message=error_message)
def flush_log_buffer(self): def flush_log_buffer(self):
"""No longer needed - kept for compatibility.""" """No longer needed - kept for compatibility."""