[QGIS Commit] r8491 - trunk/qgis/src/app
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Wed May 21 17:09:38 EDT 2008
Author: wonder
Date: 2008-05-21 17:09:37 -0400 (Wed, 21 May 2008)
New Revision: 8491
Modified:
trunk/qgis/src/app/qgspythondialog.cpp
trunk/qgis/src/app/qgspythonutils.cpp
trunk/qgis/src/app/qgspythonutils.h
Log:
better handling of python errors raised during initialization.
Modified: trunk/qgis/src/app/qgspythondialog.cpp
===================================================================
--- trunk/qgis/src/app/qgspythondialog.cpp 2008-05-21 17:48:06 UTC (rev 8490)
+++ trunk/qgis/src/app/qgspythondialog.cpp 2008-05-21 21:09:37 UTC (rev 8491)
@@ -43,7 +43,7 @@
// when using Py_single_input the return value will be always null
// we're using custom hooks for output and exceptions to show output in console
- if (QgsPythonUtils::runString(command))
+ if (QgsPythonUtils::runStringUnsafe(command))
{
QgsPythonUtils::evalString("sys.stdout.data", output);
QgsPythonUtils::runString("sys.stdout.data = ''");
Modified: trunk/qgis/src/app/qgspythonutils.cpp
===================================================================
--- trunk/qgis/src/app/qgspythonutils.cpp 2008-05-21 17:48:06 UTC (rev 8490)
+++ trunk/qgis/src/app/qgspythonutils.cpp 2008-05-21 21:09:37 UTC (rev 8491)
@@ -22,6 +22,7 @@
#include "qgsapplication.h"
#include "qgslogger.h"
+#include "qgsmessageoutput.h"
#include <QMessageBox>
#include <QStringList>
@@ -51,32 +52,25 @@
runString("sys.path = [\"" + homePluginsPath() + "\", \"" + pythonPath() + "\", \"" + pluginsPath() + "\"] + sys.path");
// import SIP
- if (!runString("from sip import wrapinstance, unwrapinstance"))
+ if (!runString("from sip import wrapinstance, unwrapinstance",
+ QObject::tr("Couldn't load SIP module.") + "\n" + QObject::tr("Python support will be disabled.")))
{
- QMessageBox::warning(0, QObject::tr("Python error"),
- QObject::tr("Couldn't load SIP module.\nPython support will be disabled."));
- PyErr_Clear();
exitPython();
return;
}
// import Qt bindings
- if (!runString("from PyQt4 import QtCore, QtGui"))
+ if (!runString("from PyQt4 import QtCore, QtGui",
+ QObject::tr("Couldn't load PyQt4.") + "\n" + QObject::tr("Python support will be disabled.")))
{
- QMessageBox::warning(0, QObject::tr("Python error"),
- QObject::tr("Couldn't load PyQt bindings.\nPython support will be disabled."));
- PyErr_Clear();
exitPython();
return;
}
// import QGIS bindings
- if (!runString("from qgis.core import *") ||
- !runString("from qgis.gui import *"))
+ QString error_msg = QObject::tr("Couldn't load PyQGIS.") + "\n" + QObject::tr("Python support will be disabled.");
+ if (!runString("from qgis.core import *", error_msg) || !runString("from qgis.gui import *", error_msg))
{
- QMessageBox::warning(0, QObject::tr("Python error"),
- QObject::tr("Couldn't load QGIS bindings.\nPython support will be disabled."));
- PyErr_Clear();
exitPython();
return;
}
@@ -162,14 +156,44 @@
}
-bool QgsPythonUtils::runString(const QString& command)
+bool QgsPythonUtils::runStringUnsafe(const QString& command)
{
PyRun_String(command.toLocal8Bit().data(), Py_single_input, mMainDict, mMainDict);
-
return (PyErr_Occurred() == 0);
}
+bool QgsPythonUtils::runString(const QString& command, QString msgOnError)
+{
+ bool res = runStringUnsafe(command);
+ if (res)
+ return true;
+
+ // an error occured
+ // fetch error details and show it
+ QString err_type, err_value;
+ getError(err_type, err_value);
+
+ if (msgOnError.isEmpty())
+ {
+ // use some default message if custom hasn't been specified
+ msgOnError = QObject::tr("An error occured during execution of following code:") + "\n<tt>" + command + "</tt>";
+ }
+ msgOnError.replace("\n", "<br>");
+ QString str = msgOnError + "<br><br>" + QObject::tr("Error details:") + "<br>"
+ + QObject::tr("Type:") + " <b>" + err_type + "</b><br>"
+ + QObject::tr("Value:") + " <b>" + err_value + "</b>";
+
+ // TODO: show sys.path, local variables, traceback
+
+ QgsMessageOutput* msg = QgsMessageOutput::createMessageOutput();
+ msg->setTitle(QObject::tr("Python error"));
+ msg->setMessage(str, QgsMessageOutput::MessageHtml);
+ msg->showMessage();
+
+ return res;
+}
+
QString QgsPythonUtils::getTypeAsString(PyObject* obj)
{
if (obj == NULL)
@@ -207,7 +231,7 @@
PyObject* err_value;
PyObject* err_tb;
- // get the exception information
+ // get the exception information and clear error
PyErr_Fetch(&err_type, &err_value, &err_tb);
// get exception's class name
@@ -223,8 +247,10 @@
else
errorText.clear();
- // clear exception
- PyErr_Clear();
+ // cleanup
+ Py_XDECREF(err_type);
+ Py_XDECREF(err_value);
+ Py_XDECREF(err_tb);
return true;
}
@@ -373,29 +399,16 @@
{
QString pluginPythonVar = "plugins['" + packageName + "']";
+ QString errMsg = QObject::tr("Couldn't load plugin ") + packageName;
+
// create an instance of the plugin
- if (!runString(pluginPythonVar + " = " + packageName + ".classFactory(iface)"))
- {
- PyErr_Print(); // just print to console
- PyErr_Clear();
-
- QMessageBox::warning(0, QObject::tr("Python error"),
- QObject::tr("Couldn't load plugin ") + packageName +
- QObject::tr(" due an error when calling its classFactory() method"));
+ if (!runString(pluginPythonVar + " = " + packageName + ".classFactory(iface)",
+ errMsg + QObject::tr(" due an error when calling its classFactory() method")))
return false;
- }
// initGui
- if (!runString(pluginPythonVar + ".initGui()"))
- {
- PyErr_Print(); // just print to console
- PyErr_Clear();
-
- QMessageBox::warning(0, QObject::tr("Python error"),
- QObject::tr("Couldn't load plugin ") + packageName +
- QObject::tr(" due an error when calling its initGui() method"));
+ if (!runString(pluginPythonVar + ".initGui()", errMsg + QObject::tr(" due an error when calling its initGui() method")))
return false;
- }
return true;
}
@@ -406,16 +419,12 @@
// unload and delete plugin!
QString varName = "plugins['" + packageName + "']";
- if (!runString(varName + ".unload()") ||
- !runString("del " + varName))
- {
- PyErr_Print(); // just print to console
- PyErr_Clear();
-
- QMessageBox::warning(0, QObject::tr("Python error"),
- QObject::tr("Error while unloading plugin ") + packageName);
+ QString errMsg = QObject::tr("Error while unloading plugin ") + packageName;
+
+ if (!runString(varName + ".unload()", errMsg))
return false;
- }
+ if (!runString("del " + varName, errMsg))
+ return false;
return true;
}
Modified: trunk/qgis/src/app/qgspythonutils.h
===================================================================
--- trunk/qgis/src/app/qgspythonutils.h 2008-05-21 17:48:06 UTC (rev 8490)
+++ trunk/qgis/src/app/qgspythonutils.h 2008-05-21 21:09:37 UTC (rev 8491)
@@ -53,9 +53,14 @@
//! run a statement (wrapper for PyRun_String)
//! this command is more advanced as enables error checking etc.
+ //! when an exception is raised, it shows dialog with exception details
//! @return true if no error occured
- static bool runString(const QString& command);
+ static bool runString(const QString& command, QString msgOnError = QString());
+ //! run a statement, error reporting is not done
+ //! @return true if no error occured
+ static bool runStringUnsafe(const QString& command);
+
static bool evalString(const QString& command, QString& result);
//! @return object's type name as a string
More information about the QGIS-commit
mailing list