Skip to content

Commit

Permalink
Add stack trace button to message bar for Python errors
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanW2 committed Oct 1, 2015
1 parent 401f43c commit 1e6c890
Showing 1 changed file with 70 additions and 21 deletions.
91 changes: 70 additions & 21 deletions python/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

from PyQt4.QtCore import QCoreApplication, QLocale
from PyQt4.QtGui import QPushButton
from qgis.core import QGis, QgsExpression, QgsMessageLog, qgsfunction
from qgis.core import QGis, QgsExpression, QgsMessageLog, qgsfunction, QgsMessageOutput
from qgis.gui import QgsMessageBar

import sys
Expand All @@ -41,6 +41,7 @@
import warnings
import codecs
import time
import functools

# ######################
# ERROR HANDLING
Expand All @@ -63,27 +64,14 @@ def showWarning(message, category, filename, lineno, file=None, line=None):


def showException(type, value, tb, msg, messagebar=False):
lst = traceback.format_exception(type, value, tb)
if msg is None:
msg = QCoreApplication.translate('Python', 'An error has occured while executing Python code:')
txt = '<font color="red">%s</font><br><br><pre>' % msg
for s in lst:
txt += s.decode('utf-8', 'replace')
txt += '</pre><br>%s<br>%s<br><br>' % (QCoreApplication.translate('Python', 'Python version:'), sys.version)
txt += '<br>%s<br>%s %s, %s<br><br>' % (
QCoreApplication.translate('Python', 'QGIS version:'), QGis.QGIS_VERSION, QGis.QGIS_RELEASE_NAME,
QGis.QGIS_DEV_VERSION)
txt += '%s %s' % (QCoreApplication.translate('Python', 'Python path:'), str(sys.path))
txt = txt.replace('\n', '<br>')
txt = txt.replace(' ', '&nbsp; ') # preserve whitespaces for nicer output

from qgis.core import QgsMessageOutput

title = QCoreApplication.translate('Python', 'Python error')
logmessage = ''
for s in lst:
for s in traceback.format_exception(type, value, tb):
logmessage += s.decode('utf-8', 'replace')

title = QCoreApplication.translate('Python', 'Python error')
QgsMessageLog.logMessage(logmessage, title)

if messagebar and iface:
Expand All @@ -94,14 +82,75 @@ def showException(type, value, tb, msg, messagebar=False):

widget = iface.messageBar().createMessage(title, msg + " See message log (Python Error) for more details.")
widget.setProperty("Error", msg)
button = QPushButton("View message log", pressed=iface.openMessageLog)
stackbutton = QPushButton("Stack trace", pressed=functools.partial(open_stack_dialog, type, value, tb, msg))
button = QPushButton("View message log", pressed=show_message_log)
widget.layout().addWidget(stackbutton)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING)
else:
msg = QgsMessageOutput.createMessageOutput()
msg.setTitle()
msg.setMessage(txt, QgsMessageOutput.MessageHtml)
msg.showMessage()
open_stack_dialog(type, value, tb, msg)

def show_message_log(pop_error=True):
if pop_error:
iface.messageBar().popWidget()

iface.openMessageLog()


def open_stack_dialog(type, value, tb, msg, pop_error=True):
if pop_error:
iface.messageBar().popWidget()

if msg is None:
msg = QCoreApplication.translate('Python', 'An error has occured while executing Python code:')

# TODO Move this to a template HTML file
txt = '''<font color="red"><b>{msg}</b></font>
<br>
<h3>{main_error}</h3>
<pre>
{error}
</pre>
<br>
<b>{version_label}</b> {num}
<br>
<b>{qgis_label}</b> {qversion} {qgisrelease}, {devversion}
<br>
<h4>{pypath_label}</h4>
<ul>
{pypath}
</ul>'''

error = ''
lst = traceback.format_exception(type, value, tb)
for s in lst:
error += s.decode('utf-8', 'replace')
error = error.replace('\n', '<br>')

main_error = lst[-1].decode('utf-8', 'replace')

version_label = QCoreApplication.translate('Python', 'Python version:')
qgis_label = QCoreApplication.translate('Python', 'QGIS version:')
pypath_label = QCoreApplication.translate('Python', 'Python Path:')
txt = txt.format(msg=msg,
main_error=main_error,
error=error,
version_label=version_label,
num=sys.version,
qgis_label=qgis_label,
qversion=QGis.QGIS_VERSION,
qgisrelease=QGis.QGIS_RELEASE_NAME,
devversion=QGis.QGIS_DEV_VERSION,
pypath_label=pypath_label,
pypath="".join("<li>{}</li>".format(path) for path in sys.path))

txt = txt.replace(' ', '&nbsp; ') # preserve whitespaces for nicer output

dlg = QgsMessageOutput.createMessageOutput()
dlg.setTitle(msg)
dlg.setMessage(txt, QgsMessageOutput.MessageHtml)
dlg.showMessage()



def qgis_excepthook(type, value, tb):
Expand Down

0 comments on commit 1e6c890

Please sign in to comment.