mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Add support for VirtualErrorHandlers in core sip
Unfortunately requires a bunch of code to be duplicated from QgsPythonUtilsImpl::getTraceback() into core.sip, but there's no way to avoid this
This commit is contained in:
parent
53e7ef88a3
commit
d63d560eb3
@ -1,6 +1,93 @@
|
||||
%Module(name=qgis._core,
|
||||
keyword_arguments="Optional")
|
||||
|
||||
%ModuleCode
|
||||
|
||||
#include "qgsprocessingexception.h"
|
||||
|
||||
QString getTraceback()
|
||||
{
|
||||
#define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;}
|
||||
|
||||
// acquire global interpreter lock to ensure we are in a consistent state
|
||||
PyGILState_STATE gstate;
|
||||
gstate = PyGILState_Ensure();
|
||||
|
||||
QString errMsg;
|
||||
QString result;
|
||||
|
||||
PyObject *modStringIO = nullptr;
|
||||
PyObject *modTB = nullptr;
|
||||
PyObject *obStringIO = nullptr;
|
||||
PyObject *obResult = nullptr;
|
||||
|
||||
PyObject *type, *value, *traceback;
|
||||
|
||||
PyErr_Fetch( &type, &value, &traceback );
|
||||
PyErr_NormalizeException( &type, &value, &traceback );
|
||||
|
||||
const char *iomod = "io";
|
||||
|
||||
modStringIO = PyImport_ImportModule( iomod );
|
||||
if ( !modStringIO )
|
||||
TRACEBACK_FETCH_ERROR( QString( "can't import %1" ).arg( iomod ) );
|
||||
|
||||
obStringIO = PyObject_CallMethod( modStringIO, ( char * ) "StringIO", nullptr );
|
||||
|
||||
/* Construct a cStringIO object */
|
||||
if ( !obStringIO )
|
||||
TRACEBACK_FETCH_ERROR( "cStringIO.StringIO() failed" );
|
||||
|
||||
modTB = PyImport_ImportModule( "traceback" );
|
||||
if ( !modTB )
|
||||
TRACEBACK_FETCH_ERROR( "can't import traceback" );
|
||||
|
||||
obResult = PyObject_CallMethod( modTB, ( char * ) "print_exception",
|
||||
( char * ) "OOOOO",
|
||||
type, value ? value : Py_None,
|
||||
traceback ? traceback : Py_None,
|
||||
Py_None,
|
||||
obStringIO );
|
||||
|
||||
if ( !obResult )
|
||||
TRACEBACK_FETCH_ERROR( "traceback.print_exception() failed" );
|
||||
|
||||
Py_DECREF( obResult );
|
||||
|
||||
obResult = PyObject_CallMethod( obStringIO, ( char * ) "getvalue", nullptr );
|
||||
if ( !obResult )
|
||||
TRACEBACK_FETCH_ERROR( "getvalue() failed." );
|
||||
|
||||
/* And it should be a string all ready to go - duplicate it. */
|
||||
if ( !PyUnicode_Check( obResult ) )
|
||||
TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" );
|
||||
|
||||
result = QString::fromUtf8( PyUnicode_AsUTF8( obResult ) );
|
||||
|
||||
done:
|
||||
|
||||
// All finished - first see if we encountered an error
|
||||
if ( result.isEmpty() && !errMsg.isEmpty() )
|
||||
{
|
||||
result = errMsg;
|
||||
}
|
||||
|
||||
Py_XDECREF( modStringIO );
|
||||
Py_XDECREF( modTB );
|
||||
Py_XDECREF( obStringIO );
|
||||
Py_XDECREF( obResult );
|
||||
Py_XDECREF( value );
|
||||
Py_XDECREF( traceback );
|
||||
Py_XDECREF( type );
|
||||
|
||||
// we are done calling python API, release global interpreter lock
|
||||
PyGILState_Release( gstate );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
%End
|
||||
|
||||
%Import QtXml/QtXmlmod.sip
|
||||
%Import QtNetwork/QtNetworkmod.sip
|
||||
%Import QtSql/QtSqlmod.sip
|
||||
@ -413,3 +500,7 @@
|
||||
%Include expression/qgsexpressionnodeimpl.sip
|
||||
%Include expression/qgsexpressionnode.sip
|
||||
%Include expression/qgsexpressionfunction.sip
|
||||
|
||||
%VirtualErrorHandler processing_exception_handler
|
||||
throw QgsProcessingException( getTraceback() );
|
||||
%End
|
||||
|
Loading…
x
Reference in New Issue
Block a user