bool QgsPythonUtilsImpl::runString( const QString& command, QString msgOnError, bool single ) { bool res = runStringUnsafe( command, single ); if ( res ) return true; if ( msgOnError.isEmpty() ) { // use some default message if custom hasn't been specified msgOnError = QObject::tr( "An error occurred during execution of following code:" ) + "\n<tt>" + command + "</tt>"; } // TODO: use python implementation QString traceback = getTraceback(); QString path, version; evalString( "str(sys.path)", path ); evalString( "sys.version", version ); QString str = "<font color=\"red\">" + msgOnError + "</font><br><pre>\n" + traceback + "\n</pre>" + QObject::tr( "Python version:" ) + "<br>" + version + "<br><br>" + QObject::tr( "QGIS version:" ) + "<br>" + QString( "%1 '%2', %3" ).arg( QGis::QGIS_VERSION, QGis::QGIS_RELEASE_NAME, QGis::QGIS_DEV_VERSION ) + "<br><br>" + QObject::tr( "Python path:" ) + "<br>" + path; str.replace( '\n', "<br>" ).replace( " ", " " ); qDebug() << str; QgsMessageOutput* msg = QgsMessageOutput::createMessageOutput(); msg->setTitle( QObject::tr( "Python error" ) ); msg->setMessage( str, QgsMessageOutput::MessageHtml ); msg->showMessage(); return res; }
void raise3(Box* arg0, Box* arg1, Box* arg2) { // TODO switch this to PyErr_Normalize if (arg2 == None) arg2 = getTraceback(); if (isSubclass(arg0->cls, type_cls)) { BoxedClass* c = static_cast<BoxedClass*>(arg0); if (isSubclass(c, BaseException)) { Box* exc_obj; if (isSubclass(arg1->cls, BaseException)) { exc_obj = arg1; c = exc_obj->cls; } else if (arg1 != None) { exc_obj = runtimeCall(c, ArgPassSpec(1), arg1, NULL, NULL, NULL, NULL); } else { exc_obj = runtimeCall(c, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); } raiseRaw(ExcInfo(c, exc_obj, arg2)); } } if (isSubclass(arg0->cls, BaseException)) { if (arg1 != None) raiseExcHelper(TypeError, "instance exception may not have a separate value"); raiseRaw(ExcInfo(arg0->cls, arg0, arg2)); } raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not %s", getTypeName(arg0)); }
bool QgsPythonUtilsImpl::runString( const QString& command, QString msgOnError ) { bool res = runStringUnsafe( command ); if ( res ) return true; 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>"; } QString traceback = getTraceback(); QString path, version; evalString( "str(sys.path)", path ); evalString( "sys.version", version ); QString str = "<font color=\"red\">" + msgOnError + "</font><br><br>" + traceback + "<br>" + QObject::tr( "Python version:" ) + "<br>" + version + "<br><br>" + QObject::tr( "Python path:" ) + "<br>" + path; str.replace( "\n", "<br>" ).replace( " ", " " ); QgsMessageOutput* msg = QgsMessageOutput::createMessageOutput(); msg->setTitle( QObject::tr( "Python error" ) ); msg->setMessage( str, QgsMessageOutput::MessageHtml ); msg->showMessage(); return res; }
// Have a special helper function for syntax errors, since we want to include the location // of the syntax error in the traceback, even though it is not part of the execution: void raiseSyntaxError(const char* msg, int lineno, int col_offset, const std::string& file, const std::string& func) { Box* exc = runtimeCall(SyntaxError, ArgPassSpec(1), boxStrConstant(msg), NULL, NULL, NULL, NULL); auto tb = getTraceback(); std::vector<const LineInfo*> entries = tb->lines; entries.push_back(new LineInfo(lineno, col_offset, file, func)); raiseRaw(ExcInfo(exc->cls, exc, new BoxedTraceback(std::move(entries)))); }
void _printStacktrace() { printTraceback(getTraceback()); }
void raiseExc(Box* exc_obj) { raiseRaw(ExcInfo(exc_obj->cls, exc_obj, getTraceback())); }