@@ -87,3 +87,48 @@ def version_from_string(version_str):
87
87
]
88
88
89
89
api_versions_tuple = [Version .from_string (v ) for v in api_versions ]
90
+
91
+
92
+ def crash_handler ():
93
+ """Implements minimal handling of an exception crashing the application.
94
+ This function tries to log the exception to a log file and display
95
+ a minimal crash dialog to the user.
96
+ This function is supposed to be called from inside an except blog.
97
+ """
98
+ # First try to get traceback information and write it to a log file
99
+ # with minimum chance to fail.
100
+ import sys
101
+ from tempfile import NamedTemporaryFile
102
+ import traceback
103
+ trace = traceback .format_exc ()
104
+ logfile = None
105
+ try :
106
+ with NamedTemporaryFile (suffix = '.log' , prefix = 'picard-crash-' , delete = False ) as f :
107
+ f .write (trace .encode (errors = "replace" ))
108
+ logfile = f .name
109
+ except : # noqa: E722,F722 # pylint: disable=bare-except
110
+ print ("Failed writing log file {0}" .format (logfile ), file = sys .stderr )
111
+ logfile = None
112
+
113
+ # Display the crash information to the user as a dialog. This requires
114
+ # importing Qt5 and has some potential to fail if things are broken.
115
+ from PyQt5 .QtCore import Qt , QUrl
116
+ from PyQt5 .QtWidgets import QApplication , QMessageBox
117
+ # assigning QApplication to a variable is required to keep the object alive
118
+ _unused = QApplication (sys .argv ) # noqa: F841
119
+ msgbox = QMessageBox ()
120
+ msgbox .setIcon (QMessageBox .Critical )
121
+ msgbox .setWindowTitle ("Picard terminated unexpectedly" )
122
+ msgbox .setTextFormat (Qt .RichText )
123
+ msgbox .setText (
124
+ 'An unexpected error has caused Picard to crash. '
125
+ 'Please report this issue on the <a href="https://tickets.metabrainz.org/projects/PICARD">MusicBrainz bug tracker</a>.' )
126
+ if logfile :
127
+ logfile_url = QUrl .fromLocalFile (logfile )
128
+ msgbox .setInformativeText (
129
+ 'A logfile has been written to <a href="{0}">{1}</a>.'
130
+ .format (logfile_url .url (), logfile ))
131
+ msgbox .setDetailedText (trace )
132
+ msgbox .setStandardButtons (QMessageBox .Close )
133
+ msgbox .setDefaultButton (QMessageBox .Close )
134
+ msgbox .exec_ ()
0 commit comments