diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py index 7008ba64d2..dbf931b37e 100644 --- a/cura/CrashHandler.py +++ b/cura/CrashHandler.py @@ -5,14 +5,15 @@ import webbrowser import faulthandler import tempfile import os -import urllib -from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, Qt, QCoreApplication -from PyQt5.QtGui import QPixmap -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QHBoxLayout, QVBoxLayout, QLabel, QTextEdit +from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QCoreApplication +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox +from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply from UM.Logger import Logger +from UM.View.GL.OpenGL import OpenGL from UM.i18n import i18nCatalog + catalog = i18nCatalog("cura") MYPY = False @@ -23,6 +24,7 @@ else: from cura.CuraVersion import CuraDebugMode except ImportError: CuraDebugMode = False # [CodeStyle: Reflecting imported value] +CuraDebugMode = True ## TODO Remove when done. Just for debug purposes # List of exceptions that should be considered "fatal" and abort the program. # These are primarily some exception types that we simply cannot really recover from @@ -35,83 +37,145 @@ fatal_exception_types = [ SystemError, ] -def show(exception_type, value, tb): - Logger.log("c", "An uncaught exception has occurred!") - for line in traceback.format_exception(exception_type, value, tb): - for part in line.rstrip("\n").split("\n"): - Logger.log("c", part) +class CrashHandler: - if not CuraDebugMode and exception_type not in fatal_exception_types: - return + def __init__(self, exception_type, value, tb): - application = QCoreApplication.instance() - if not application: - sys.exit(1) + self.exception_type = exception_type + self.value = value + self.traceback = tb - dialog = QDialog() - dialog.setMinimumWidth(640) - dialog.setMinimumHeight(640) - dialog.setWindowTitle(catalog.i18nc("@title:window", "Crash Report")) + Logger.log("c", "An uncaught exception has occurred!") + for line in traceback.format_exception(exception_type, value, tb): + for part in line.rstrip("\n").split("\n"): + Logger.log("c", part) - layout = QVBoxLayout(dialog) + if not CuraDebugMode and exception_type not in fatal_exception_types: + return - #label = QLabel(dialog) - #pixmap = QPixmap() - #try: - # data = urllib.request.urlopen("http://www.randomkittengenerator.com/cats/rotator.php").read() - # pixmap.loadFromData(data) - #except: - # try: - # from UM.Resources import Resources - # path = Resources.getPath(Resources.Images, "kitten.jpg") - # pixmap.load(path) - # except: - # pass - #pixmap = pixmap.scaled(150, 150) - #label.setPixmap(pixmap) - #label.setAlignment(Qt.AlignCenter) - #layout.addWidget(label) + application = QCoreApplication.instance() + if not application: + sys.exit(1) - label = QLabel(dialog) - layout.addWidget(label) + self._createDialog() - #label.setScaledContents(True) - label.setText(catalog.i18nc("@label", """
A fatal exception has occurred that we could not recover from!
-Please use the information below to post a bug report at http://github.com/Ultimaker/Cura/issues
- """)) + ## Creates a modal dialog. + def _createDialog(self): - textarea = QTextEdit(dialog) - layout.addWidget(textarea) + self.dialog = QDialog() + self.dialog.setMinimumWidth(640) + self.dialog.setMinimumHeight(640) + self.dialog.setWindowTitle(catalog.i18nc("@title:window", "Crash Report")) - try: - from UM.Application import Application - version = Application.getInstance().getVersion() - except: - version = "Unknown" + layout = QVBoxLayout(self.dialog) - trace = "".join(traceback.format_exception(exception_type, value, tb)) + layout.addWidget(self._messageWidget()) + layout.addWidget(self._informationWidget()) + layout.addWidget(self._exceptionInfoWidget()) + layout.addWidget(self._logInfoWidget()) + layout.addWidget(self._userDescriptionWidget()) + layout.addWidget(self._buttonsWidget()) - crash_info = "Version: {0}\nPlatform: {1}\nQt: {2}\nPyQt: {3}\n\nException:\n{4}" - crash_info = crash_info.format(version, platform.platform(), QT_VERSION_STR, PYQT_VERSION_STR, trace) + def _messageWidget(self): + label = QLabel() + label.setText(catalog.i18nc("@label", """A fatal exception has occurred that we could not recover from!
+Please use the button below to post a bug report automatically to our servers
+ """)) - tmp_file_fd, tmp_file_path = tempfile.mkstemp(prefix = "cura-crash", text = True) - os.close(tmp_file_fd) - with open(tmp_file_path, "w") as f: - faulthandler.dump_traceback(f, all_threads=True) - with open(tmp_file_path, "r") as f: - data = f.read() + return label - msg = "-------------------------\n" - msg += data - crash_info += "\n\n" + msg + def _informationWidget(self): + group = QGroupBox() + group.setTitle("System information") + layout = QVBoxLayout() + label = QLabel() - textarea.setText(crash_info) + try: + from UM.Application import Application + version = Application.getInstance().getVersion() + except: + version = "Unknown" - buttons = QDialogButtonBox(QDialogButtonBox.Close, dialog) - layout.addWidget(buttons) - buttons.addButton(catalog.i18nc("@action:button", "Open Web Page"), QDialogButtonBox.HelpRole) - buttons.rejected.connect(dialog.close) - buttons.helpRequested.connect(lambda: webbrowser.open("http://github.com/Ultimaker/Cura/issues")) + crash_info = "Version: {0}