Add more error handling
offlate/ui/editor.py
181 | 181 | ||
182 | 182 | worker = [] | |
183 | 183 | for f in files: | |
184 | - | worker.append(ExternalRunnable(f)) | |
184 | + | worker.append(ExternalRunnable(self, f)) | |
185 | 185 | ||
186 | - | worker2 = WatchRunnable(self.project, len(worker)) | |
186 | + | worker2 = WatchRunnable(self, self.project, len(worker)) | |
187 | 187 | worker2.signals.finished.connect(self.editedExternals) | |
188 | 188 | worker2.signals.progress.connect(self.intermediateReloadContent) | |
189 | 189 | for i in range(0, len(worker)): | |
… | |||
446 | 446 | self.setLabels(self.tr("Uploading {}...").format(self.tabs.currentWidget().project.name)) | |
447 | 447 | worker = UploadRunnable(self.tabs.currentWidget()) | |
448 | 448 | worker.signals.finished.connect(self.sent) | |
449 | + | worker.signals.error.connect(self.reportError) | |
449 | 450 | self.threadpool.start(worker) | |
450 | 451 | ||
451 | 452 | def sent(self, name): | |
… | |||
457 | 458 | worker = UpdateRunnable(self.tabs.currentWidget()) | |
458 | 459 | worker.signals.finished.connect(self.updated) | |
459 | 460 | worker.signals.progress.connect(self.reportProgress) | |
461 | + | worker.signals.error.connect(self.reportError) | |
460 | 462 | self.threadpool.start(worker) | |
461 | 463 | ||
462 | 464 | def updated(self, name): | |
… | |||
468 | 470 | def reportProgress(self, name, progress): | |
469 | 471 | self.setProgresses(progress) | |
470 | 472 | ||
473 | + | def reportError(self, name, error): | |
474 | + | dialog = QMessageBox() | |
475 | + | dialog.setText(error) | |
476 | + | dialog.exec_() | |
477 | + | ||
471 | 478 | def setLabels(self, value): | |
472 | 479 | self.actionLabel.setText(value) | |
473 | 480 | self.projectManagerWindow.projectManagerWidget.actionLabel.setText(value) | |
… | |||
614 | 621 | self.setGeometry(0, 0, 800, 600) | |
615 | 622 | self.setWindowTitle('Offlate') | |
616 | 623 | ||
617 | - | class UploadRunnable(QRunnable, RunnableCallback): | |
618 | - | def __init__(self, widget): | |
624 | + | class UploadRunnable(RunnableCallback): | |
625 | + | def __init__(self, parent, widget): | |
619 | 626 | super().__init__() | |
620 | 627 | self.widget = widget | |
628 | + | self.parent = widget | |
621 | 629 | self.signals = RunnableSignals() | |
622 | 630 | self.oldamount = -1 | |
623 | 631 | self.error = None | |
624 | 632 | self.name = self.widget.project.name | |
625 | 633 | ||
626 | - | def run(self): | |
634 | + | def do_run(self): | |
627 | 635 | self.widget.send() | |
636 | + | ||
637 | + | def do_finish(self): | |
628 | 638 | self.signals.finished.emit(self.name) | |
629 | 639 | ||
630 | - | class UpdateRunnable(QRunnable, RunnableCallback): | |
640 | + | class UpdateRunnable(RunnableCallback): | |
631 | 641 | def __init__(self, widget): | |
632 | 642 | super().__init__() | |
633 | 643 | self.widget = widget | |
644 | + | self.parent = widget | |
634 | 645 | self.signals = RunnableSignals() | |
635 | 646 | self.oldamount = -1 | |
636 | 647 | self.error = None | |
637 | 648 | self.name = self.widget.project.name | |
638 | 649 | ||
639 | - | def run(self): | |
650 | + | def do_run(self): | |
640 | 651 | self.widget.update(Interface()) | |
652 | + | ||
653 | + | def do_finish(self): | |
641 | 654 | self.signals.finished.emit(self.name) | |
642 | 655 | ||
643 | - | class ExternalRunnable(QRunnable, RunnableCallback): | |
644 | - | def __init__(self, mfile): | |
656 | + | class ExternalRunnable(RunnableCallback): | |
657 | + | def __init__(self, parent, mfile): | |
645 | 658 | super().__init__() | |
646 | 659 | self.mfile = mfile | |
660 | + | self.parent = parent | |
647 | 661 | self.signals = RunnableSignals() | |
648 | 662 | self.oldamount = -1 | |
649 | 663 | self.error = None | |
650 | 664 | self.name = "" | |
651 | 665 | ||
652 | - | def run(self): | |
653 | - | # Try to open file with the default application | |
654 | - | try: | |
655 | - | if platform.system() == 'Darwin': | |
656 | - | subprocess.run(['open', self.mfile]) | |
657 | - | elif platform.system() == 'Windows': | |
658 | - | subprocess.run(['start', self.mfile]) | |
659 | - | else: | |
660 | - | subprocess.run(['xdg-open', self.mfile]) | |
661 | - | except: | |
662 | - | print(sys.exc_info()) | |
663 | - | pass | |
666 | + | def do_run(self): | |
667 | + | if platform.system() == 'Darwin': | |
668 | + | subprocess.run(['open', self.mfile]) | |
669 | + | elif platform.system() == 'Windows': | |
670 | + | subprocess.run(['start', self.mfile]) | |
671 | + | else: | |
672 | + | subprocess.run(['xdg-open', self.mfile]) | |
673 | + | ||
674 | + | def do_finish(self): | |
664 | 675 | self.signals.finished.emit("") | |
665 | 676 | ||
666 | 677 | class MyHandler(FileSystemEventHandler): | |
… | |||
671 | 682 | def on_modified(self, event): | |
672 | 683 | self.parent.signals.progress.emit("", 0) | |
673 | 684 | ||
674 | - | class WatchRunnable(QRunnable, RunnableCallback): | |
675 | - | def __init__(self, project, size): | |
685 | + | class WatchRunnable(RunnableCallback): | |
686 | + | def __init__(self, parent, project, size): | |
676 | 687 | super().__init__() | |
688 | + | self.parent = parent | |
677 | 689 | self.project = project | |
678 | 690 | self.signals = RunnableSignals() | |
679 | 691 | self.oldamount = -1 | |
… | |||
689 | 701 | for f in files: | |
690 | 702 | self.observer.schedule(event_handler, str(Path(f).parent), recursive=True) | |
691 | 703 | ||
692 | - | def run(self): | |
704 | + | def do_run(self): | |
693 | 705 | self.observer.start() | |
694 | 706 | while self.size > 0: | |
695 | 707 | sleep(0.2) | |
696 | 708 | self.observer.stop() | |
697 | 709 | self.observer.join() | |
710 | + | ||
711 | + | def do_finish(self): | |
698 | 712 | self.signals.finished.emit("") | |
699 | 713 | ||
700 | 714 | def stop(self, name): |
offlate/ui/manager.py
283 | 283 | worker.signals.finished.connect(self.finishReport) | |
284 | 284 | self.threadpool.start(worker) | |
285 | 285 | ||
286 | - | class NewRunnable(QRunnable, RunnableCallback): | |
286 | + | class NewRunnable(RunnableCallback): | |
287 | 287 | def __init__(self, parent, name, lang, system, info): | |
288 | 288 | super().__init__() | |
289 | 289 | self.name = name | |
… | |||
305 | 305 | self.info, self.error) | |
306 | 306 | self.parent.filter() | |
307 | 307 | ||
308 | - | class EditRunnable(QRunnable, RunnableCallback): | |
308 | + | class EditRunnable(RunnableCallback): | |
309 | 309 | def __init__(self, parent, name, lang, system, info): | |
310 | 310 | super().__init__() | |
311 | 311 | self.name = name |
offlate/ui/parallel.py
15 | 15 | #### | |
16 | 16 | ||
17 | 17 | from PyQt5.QtCore import * | |
18 | + | from PyQt5.QtWidgets import * | |
19 | + | ||
18 | 20 | from ..formats.exception import UnsupportedFormatException | |
19 | 21 | from ..systems.exception import ProjectNotFoundSystemException | |
20 | 22 | from ..systems.callback import SystemCallback | |
21 | 23 | ||
22 | - | class RunnableCallback(SystemCallback): | |
24 | + | import sys | |
25 | + | ||
26 | + | class RunnableCallback(SystemCallback, QRunnable): | |
27 | + | def run(self): | |
28 | + | try: | |
29 | + | self.do_run() | |
30 | + | except: | |
31 | + | info = sys.exc_info() | |
32 | + | self.reportError(info[1], info[2]) | |
33 | + | self.do_finish() | |
34 | + | ||
23 | 35 | def reportProgress(self, amount): | |
24 | 36 | if int(round(amount)) > self.oldamount: | |
25 | 37 | self.oldamount = int(round(amount)) | |
26 | 38 | self.signals.progress.emit(self.name, amount) | |
27 | 39 | ||
40 | + | def reportError(self, error, trace): | |
41 | + | traceback = '' | |
42 | + | while trace is not None: | |
43 | + | traceback = traceback + str(trace.tb_frame) + "\n" | |
44 | + | trace = trace.tb_next | |
45 | + | ||
46 | + | self.error = self.parent.tr('This action did not complete correctly. \ | |
47 | + | We received the following error message: {}.\n\nTraceback:\n\n{}\nTry \ | |
48 | + | again?'.format(error, traceback)) | |
49 | + | self.signals.error.emit(self.name, self.error) | |
50 | + | ||
28 | 51 | def project_exists(self): | |
29 | 52 | self.error = self.parent.tr('A project with the same name already exists. \ | |
30 | 53 | The new project was not created. You should first remove the same-named project.') |