Commit 7ae450f2 authored by dmMaze's avatar dmMaze
Browse files

unified error dialog

parent b8c1474f
Loading
Loading
Loading
Loading
+10 −15
Original line number Diff line number Diff line
# stealt & modified from https://github.com/zyddnys/manga-image-translator/blob/main/manga_translator/translators/chatgpt.py

from http import client
from pydoc import cli
import re
import time
from token import OP
from typing import List, Dict, Union
import yaml
import asyncio
import traceback
import time

import openai

from .base import BaseTranslator, register_translator
from utils.error_handling import create_error_dialog

OPENAPI_V1_API = int(openai.__version__.split('.')[0]) >= 1

@@ -235,20 +234,18 @@ class SakuraTranslator(BaseTranslator):
                try:
                    response = self._request_translation(prompt)
                    break
                except openai.APIError:
                except openai.APIError as e:
                    server_error_attempt += 1
                    if server_error_attempt >= self.retry_attempts:
                        self.logger.error(
                            'Sakura server error. Returning original text.')
                        create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator')
                        return '\n'.join(prompt)
                    self.logger.warn(
                        f'Restarting request due to a server error. Attempt: {server_error_attempt}')
                    time.sleep(1)
                except openai.APIConnectionError:
                except openai.APIConnectionError as e:
                    server_error_attempt += 1
                    if server_error_attempt >= self.retry_attempts:
                        self.logger.error(
                            'Sakura server error. Returning original text.')
                        create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator')
                        return '\n'.join(prompt)
                    self.logger.warn(
                        f'Restarting request due to a server connection error.Current API baseurl is "{self.api_base}" Attempt: {server_error_attempt}')
@@ -264,20 +261,18 @@ class SakuraTranslator(BaseTranslator):
                try:
                    response = self._request_translation(prompt)
                    break
                except openai.error.APIError:
                except openai.error.APIError as e:
                    server_error_attempt += 1
                    if server_error_attempt >= self.retry_attempts:
                        self.logger.error(
                            'Sakura server error. Returning original text.')
                        create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator')
                        return '\n'.join(prompt)
                    self.logger.warn(
                        f'Restarting request due to a server error. Attempt: {server_error_attempt}')
                    time.sleep(1)
                except openai.error.APIConnectionError:
                except openai.error.APIConnectionError as e:
                    server_error_attempt += 1
                    if server_error_attempt >= self.retry_attempts:
                        self.logger.error(
                            'Sakura server error. Returning original text.')
                        create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator')
                        return '\n'.join(prompt)
                    self.logger.warn(
                        f'Restarting request due to a server connection error.Current API baseurl is "{self.api_base}" Attempt: {server_error_attempt}')
+1 −1
Original line number Diff line number Diff line
@@ -380,7 +380,7 @@ class DrawingPanel(Widget):
    def initDLModule(self, module_manager: ModuleManager):
        self.module_manager = module_manager
        module_manager.canvas_inpaint_finished.connect(self.on_inpaint_finished)
        module_manager.inpaint_thread.exception_occurred.connect(self.on_inpaint_failed)
        module_manager.inpaint_thread.inpaint_failed.connect(self.on_inpaint_failed)

    def setInpaintToolWidth(self, width):
        self.inpaint_pen.setWidthF(width)
+3 −3
Original line number Diff line number Diff line
@@ -177,7 +177,8 @@ class SearchResultTree(QTreeView):
class GlobalReplaceThead(ThreadBase):

    finished = Signal()

    _thread_error_msg = 'Failed to perform replacement'
    _thread_exception_type = 'GlobalReplaceThead'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
@@ -275,8 +276,7 @@ class GlobalReplaceThead(ThreadBase):
    def on_finished(self):
        self.progress_bar.hide()

    def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''):
        super().handleRunTimeException(msg, detail, verbose)
    def on_exec_failed(self):
        self.progress_bar.hide()


+21 −14
Original line number Diff line number Diff line
@@ -8,36 +8,38 @@ from qtpy.QtWidgets import QDialog, QMessageBox, QFileDialog

from utils.logger import logger as LOGGER
from utils.io_utils import imread, imwrite
from utils.error_handling import create_error_dialog
from .config_proj import ProjImgTrans
from .stylewidgets import ProgressMessageBox


class ThreadBase(QThread):
    exception_occured = Signal(str, str, str)

    _thread_exception_type = None
    _thread_error_msg = 'Thread job failed.'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.job = None
        self.exception_occured.connect(self.handleRunTimeException)

    def on_exec_failed(self):
        return
    
    def run(self):
        if self.job is not None:
            try:
                self.job()
            except Exception as e:
                self.exception_occured.emit(self.tr('Execution error'), str(e), traceback.format_exc())
                self.on_exec_failed()
                create_error_dialog(e, self._thread_error_msg, self._thread_exception_type)
        self.job = None

    def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''):
        if detail is not None:
            msg += ': ' + detail
        LOGGER.error(msg + '\n' + verbose)
        err = QMessageBox()
        err.setText(msg)
        err.setDetailedText(verbose)
        err.exec()

class ImgSaveThread(ThreadBase):

    img_writed = Signal(str)
    _thread_exception_type = 'ImgSaveThread'
    _thread_error_msg = 'Failed to save image.'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.im_save_list = []
@@ -68,6 +70,8 @@ class ImgTransProjFileIOThread(ThreadBase):
    fin_page = Signal()
    fin_io = Signal()

    _thread_exception_type = 'ImgTransProjFileIOThread'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.proj: ProjImgTrans = None
@@ -83,13 +87,14 @@ class ImgTransProjFileIOThread(ThreadBase):
        if self.fin_counter == self.num_pages:
            self.progress_bar.hide()

    def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''):
        super().handleRunTimeException(msg, detail, verbose)
    def on_exec_failed(self):
        self.progress_bar.hide()


class ExportDocThread(ImgTransProjFileIOThread):

    _thread_error_msg = 'Failed to export Doc'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.progress_bar.setTaskName(self.tr('Export as doc...'))
@@ -124,6 +129,8 @@ class ExportDocThread(ImgTransProjFileIOThread):

class ImportDocThread(ImgTransProjFileIOThread):

    _thread_error_msg = 'Failed to import Doc'

    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.progress_bar.setTaskName(self.tr('Import doc...'))
+25 −10
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@ from typing import List, Union
from pathlib import Path
import subprocess
from functools import partial
import time

from qtpy.QtWidgets import QFileDialog, QMenu, QHBoxLayout, QVBoxLayout, QApplication, QStackedWidget, QSplitter, QListWidget, QShortcut, QListWidgetItem, QMessageBox, QTextEdit, QPlainTextEdit
from qtpy.QtCore import Qt, QPoint, QSize, QEvent, Signal
@@ -14,6 +13,7 @@ from utils.logger import logger as LOGGER
from utils.text_processing import is_cjk, full_len, half_len
from utils.textblock import TextBlock
from utils import shared
from utils.error_handling import create_error_dialog
from modules.translators.trans_chatgpt import GPTTranslator
from .misc import parse_stylesheet, set_html_family
from utils.config import ProgramConfig, pcfg, save_config, text_styles, save_text_styles, load_textstyle_from
@@ -65,11 +65,14 @@ class MainWindow(mainwindow_cls):
    translator = None

    restart_signal = Signal()
    create_errdialog = Signal(str, str, str)
    
    def __init__(self, app: QApplication, config: ProgramConfig, open_dir='', **exec_args) -> None:
        
        super().__init__()

        shared.create_errdialog_in_mainthread = self.create_errdialog.emit
        self.create_errdialog.connect(self.on_create_errdialog)

        self.app = app
        self.setupThread()
        self.setupUi()
@@ -346,9 +349,7 @@ class MainWindow(mainwindow_cls):
            self.opening_dir = False
        except Exception as e:
            self.opening_dir = False
            LOGGER.exception(e)
            LOGGER.warning("Failed to load project from " + directory)
            self.module_manager.handleRunTimeException(self.tr('Failed to load project ') + directory, '')
            create_error_dialog(e, self.tr('Failed to load project ') + directory)
            return
        
    def dropOpenDir(self, directory: str):
@@ -367,9 +368,7 @@ class MainWindow(mainwindow_cls):
            self.opening_dir = False
        except Exception as e:
            self.opening_dir = False
            LOGGER.exception(e)
            LOGGER.warning("Failed to load project from " + json_path)
            self.module_manager.handleRunTimeException(self.tr('Failed to load project ') + json_path, '')
            create_error_dialog(e, self.tr('Failed to load project from') + json_path)
        
    def updatePageList(self):
        if self.pageList.count() != 0:
@@ -1041,7 +1040,7 @@ class MainWindow(mainwindow_cls):
            save_config()
            self.textPanel.formatpanel.textstyle_panel.style_area.setStyles(text_styles)
        except Exception as e:
            self.module_manager.handleRunTimeException(self.tr(f'Failed to load from {p}'), str(e))
            create_error_dialog(e, self.tr(f'Failed to load from {p}'))

    def export_tstyles(self):
        ddir = osp.dirname(pcfg.text_styles_path)
@@ -1062,7 +1061,7 @@ class MainWindow(mainwindow_cls):
            save_text_styles(raise_exception=True)
            save_config()
        except Exception as e:
            self.module_manager.handleRunTimeException(self.tr(f'Failed save to {savep}'), str(e))
            create_error_dialog(e, self.tr(f'Failed save to {savep}'))
            pcfg.text_styles_path = oldp

    def fold_textarea(self, fold: bool):
@@ -1223,3 +1222,19 @@ class MainWindow(mainwindow_cls):
            if pcfg.module.enable_inpaint:
                shared.pbar['inpaint'] = tqdm(range(npages), desc="Inpaint")
        self.run_imgtrans()

    def on_create_errdialog(self, error_msg: str, detail_traceback: str = '', exception_type: str = ''):
        try:
            if exception_type != '':
                shared.showed_exception.add(exception_type)
            err = QMessageBox()
            err.setText(error_msg)
            err.setDetailedText(detail_traceback)
            err.exec()
            if exception_type != '':
                shared.showed_exception.remove(exception_type)
        except:
            if exception_type in shared.showed_exception:
                shared.showed_exception.remove(exception_type)
            LOGGER.error('Failed to create error dialog')
            LOGGER.error(traceback.format_exc())
 No newline at end of file
Loading