|
1 | 1 | %Module(name=qgis._core,
|
2 | 2 | keyword_arguments="Optional")
|
3 | 3 |
|
| 4 | +%ModuleCode |
| 5 | + |
| 6 | +#include "qgsprocessingexception.h" |
| 7 | + |
| 8 | +QString getTraceback() |
| 9 | +{ |
| 10 | +#define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;} |
| 11 | + |
| 12 | + // acquire global interpreter lock to ensure we are in a consistent state |
| 13 | + PyGILState_STATE gstate; |
| 14 | + gstate = PyGILState_Ensure(); |
| 15 | + |
| 16 | + QString errMsg; |
| 17 | + QString result; |
| 18 | + |
| 19 | + PyObject *modStringIO = nullptr; |
| 20 | + PyObject *modTB = nullptr; |
| 21 | + PyObject *obStringIO = nullptr; |
| 22 | + PyObject *obResult = nullptr; |
| 23 | + |
| 24 | + PyObject *type, *value, *traceback; |
| 25 | + |
| 26 | + PyErr_Fetch( &type, &value, &traceback ); |
| 27 | + PyErr_NormalizeException( &type, &value, &traceback ); |
| 28 | + |
| 29 | + const char *iomod = "io"; |
| 30 | + |
| 31 | + modStringIO = PyImport_ImportModule( iomod ); |
| 32 | + if ( !modStringIO ) |
| 33 | + TRACEBACK_FETCH_ERROR( QString( "can't import %1" ).arg( iomod ) ); |
| 34 | + |
| 35 | + obStringIO = PyObject_CallMethod( modStringIO, ( char * ) "StringIO", nullptr ); |
| 36 | + |
| 37 | + /* Construct a cStringIO object */ |
| 38 | + if ( !obStringIO ) |
| 39 | + TRACEBACK_FETCH_ERROR( "cStringIO.StringIO() failed" ); |
| 40 | + |
| 41 | + modTB = PyImport_ImportModule( "traceback" ); |
| 42 | + if ( !modTB ) |
| 43 | + TRACEBACK_FETCH_ERROR( "can't import traceback" ); |
| 44 | + |
| 45 | + obResult = PyObject_CallMethod( modTB, ( char * ) "print_exception", |
| 46 | + ( char * ) "OOOOO", |
| 47 | + type, value ? value : Py_None, |
| 48 | + traceback ? traceback : Py_None, |
| 49 | + Py_None, |
| 50 | + obStringIO ); |
| 51 | + |
| 52 | + if ( !obResult ) |
| 53 | + TRACEBACK_FETCH_ERROR( "traceback.print_exception() failed" ); |
| 54 | + |
| 55 | + Py_DECREF( obResult ); |
| 56 | + |
| 57 | + obResult = PyObject_CallMethod( obStringIO, ( char * ) "getvalue", nullptr ); |
| 58 | + if ( !obResult ) |
| 59 | + TRACEBACK_FETCH_ERROR( "getvalue() failed." ); |
| 60 | + |
| 61 | + /* And it should be a string all ready to go - duplicate it. */ |
| 62 | + if ( !PyUnicode_Check( obResult ) ) |
| 63 | + TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" ); |
| 64 | + |
| 65 | + result = QString::fromUtf8( PyUnicode_AsUTF8( obResult ) ); |
| 66 | + |
| 67 | +done: |
| 68 | + |
| 69 | + // All finished - first see if we encountered an error |
| 70 | + if ( result.isEmpty() && !errMsg.isEmpty() ) |
| 71 | + { |
| 72 | + result = errMsg; |
| 73 | + } |
| 74 | + |
| 75 | + Py_XDECREF( modStringIO ); |
| 76 | + Py_XDECREF( modTB ); |
| 77 | + Py_XDECREF( obStringIO ); |
| 78 | + Py_XDECREF( obResult ); |
| 79 | + Py_XDECREF( value ); |
| 80 | + Py_XDECREF( traceback ); |
| 81 | + Py_XDECREF( type ); |
| 82 | + |
| 83 | + // we are done calling python API, release global interpreter lock |
| 84 | + PyGILState_Release( gstate ); |
| 85 | + |
| 86 | + return result; |
| 87 | +} |
| 88 | + |
| 89 | +%End |
| 90 | + |
4 | 91 | %Import QtXml/QtXmlmod.sip
|
5 | 92 | %Import QtNetwork/QtNetworkmod.sip
|
6 | 93 | %Import QtSql/QtSqlmod.sip
|
|
413 | 500 | %Include expression/qgsexpressionnodeimpl.sip
|
414 | 501 | %Include expression/qgsexpressionnode.sip
|
415 | 502 | %Include expression/qgsexpressionfunction.sip
|
| 503 | + |
| 504 | +%VirtualErrorHandler processing_exception_handler |
| 505 | + throw QgsProcessingException( getTraceback() ); |
| 506 | +%End |
0 commit comments