diff --git a/python/core/core.sip.in b/python/core/core.sip.in index 5332d2beade..3256aa8c53d 100644 --- a/python/core/core.sip.in +++ b/python/core/core.sip.in @@ -107,8 +107,40 @@ done: %Include core_auto.sip %VirtualErrorHandler processing_exception_handler - QString trace = getTraceback(); - QgsLogger::critical( trace ); + // 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( trace ); + throw QgsProcessingException( what ); %End