mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			152 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
%Module(name=qgis._core,
 | 
						|
        keyword_arguments="All")
 | 
						|
 | 
						|
${DEFAULTDOCSTRINGSIGNATURE}
 | 
						|
 | 
						|
%ModuleCode
 | 
						|
 | 
						|
#include "qgsexception.h"
 | 
						|
#include "qgslogger.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
 | 
						|
 | 
						|
%Import QtPrintSupport/QtPrintSupportmod.sip
 | 
						|
%Import QtWidgets/QtWidgetsmod.sip
 | 
						|
%Import QtPositioning/QtPositioningmod.sip
 | 
						|
 | 
						|
%Feature HAVE_GUI
 | 
						|
%Feature ANDROID
 | 
						|
%Feature VECTOR_MAPPED_TYPE
 | 
						|
 | 
						|
%Include conversions.sip
 | 
						|
%Include qgsexception.sip
 | 
						|
%Include typedefs.sip
 | 
						|
%Include std.sip
 | 
						|
 | 
						|
 | 
						|
%Include core_auto.sip
 | 
						|
 | 
						|
%VirtualErrorHandler processing_exception_handler
 | 
						|
    // if an explicit QgsProcessingException was raised, we don't retrieve
 | 
						|
    // and append the trace. It's too noisy for these "expected" type errors.
 | 
						|
    // For all other exceptions, it's likely a coding error in the algorithm,
 | 
						|
    // so we DO retrieve the full traceback for debugging.
 | 
						|
    PyGILState_STATE gstate;
 | 
						|
    gstate = PyGILState_Ensure();
 | 
						|
    PyTypeObject* err = reinterpret_cast< PyTypeObject* >( PyErr_Occurred() );
 | 
						|
    const bool isProcessingException = err && QString( err->tp_name ) == QStringLiteral( "QgsProcessingException" );
 | 
						|
 | 
						|
    QString what;
 | 
						|
    if ( isProcessingException )
 | 
						|
    {
 | 
						|
      PyObject *type, *value, *traceback;
 | 
						|
      PyErr_Fetch( &type, &value, &traceback );
 | 
						|
      // check whether the object is already a unicode string
 | 
						|
      if ( PyUnicode_Check( value) )
 | 
						|
      {
 | 
						|
        what = QString::fromUtf8( PyUnicode_AsUTF8( value ) );
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        PyObject* str = PyObject_Str( value );
 | 
						|
        what = QString::fromUtf8( PyUnicode_AsUTF8( str ) );
 | 
						|
        Py_XDECREF( str );
 | 
						|
      }
 | 
						|
      PyGILState_Release( gstate );
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      PyGILState_Release( gstate );
 | 
						|
      QString trace = getTraceback();
 | 
						|
      QgsLogger::critical( trace );
 | 
						|
      what = trace;
 | 
						|
    }
 | 
						|
    SIP_RELEASE_GIL( sipGILState );
 | 
						|
    throw QgsProcessingException( what );
 | 
						|
%End
 |