Skip to content

Commit

Permalink
When calling processing.run() and an QgsProcessingExpection occurs,
Browse files Browse the repository at this point in the history
don't raise a generic "something went wrong" exception but instead
ensure that the original exception with the proper error message
is raised for catching in Python instead
  • Loading branch information
nyalldawson committed Oct 8, 2020
1 parent ee7bea2 commit 2207c30
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 12 deletions.
Expand Up @@ -337,7 +337,8 @@ is passed in order to make a best guess determination of the output properties.
.. versionadded:: 3.14
%End

QVariantMap run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0, const QVariantMap &configuration = QVariantMap() ) const;
QVariantMap run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok /Out/ = 0, const QVariantMap &configuration = QVariantMap(),
bool catchExceptions = true ) const throw( QgsProcessingException );
%Docstring
Executes the algorithm using the specified ``parameters``. This method internally
creates a copy of the algorithm before running it, so it is safe to call
Expand All @@ -349,6 +350,9 @@ Algorithm progress should be reported using the supplied ``feedback`` object.

If specified, ``ok`` will be set to ``True`` if algorithm was successfully run.

If ``catchExceptions`` is set to ``False``, then QgsProcessingExceptions raised during
the algorithm run will not be automatically caught and will be raised instead.

:return: A map of algorithm outputs. These may be output layer references, or calculated
values such as statistical calculations.

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/core/Processing.py
Expand Up @@ -156,7 +156,7 @@ def runAlgorithm(algOrName, parameters, onFinish=None, feedback=None, context=No
feedback.pushInfo(
Processing.tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'))

ret, results = execute(alg, parameters, context, feedback)
ret, results = execute(alg, parameters, context, feedback, catch_exceptions=False)
if ret:
feedback.pushInfo(
Processing.tr('Results: {}').format(results))
Expand Down
20 changes: 12 additions & 8 deletions python/plugins/processing/gui/AlgorithmExecutor.py
Expand Up @@ -45,7 +45,7 @@
from qgis.utils import iface


def execute(alg, parameters, context=None, feedback=None):
def execute(alg, parameters, context=None, feedback=None, catch_exceptions=True):
"""Executes a given algorithm, showing its progress in the
progress object passed along.
Expand All @@ -58,14 +58,18 @@ def execute(alg, parameters, context=None, feedback=None):
if context is None:
context = dataobjects.createContext(feedback)

try:
results, ok = alg.run(parameters, context, feedback)
if catch_exceptions:
try:
results, ok = alg.run(parameters, context, feedback)
return ok, results
except QgsProcessingException as e:
QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical)
if feedback is not None:
feedback.reportError(e.msg)
return False, {}
else:
results, ok = alg.run(parameters, context, feedback, {}, False)
return ok, results
except QgsProcessingException as e:
QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical)
if feedback is not None:
feedback.reportError(e.msg)
return False, {}


def execute_in_place_run(alg, parameters, context=None, feedback=None, raise_exceptions=False):
Expand Down
5 changes: 4 additions & 1 deletion src/core/processing/qgsprocessingalgorithm.cpp
Expand Up @@ -445,7 +445,7 @@ QgsProcessingAlgorithm::VectorProperties QgsProcessingAlgorithm::sinkProperties(
return VectorProperties();
}

QVariantMap QgsProcessingAlgorithm::run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok, const QVariantMap &configuration ) const
QVariantMap QgsProcessingAlgorithm::run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok, const QVariantMap &configuration, bool catchExceptions ) const
{
std::unique_ptr< QgsProcessingAlgorithm > alg( create( configuration ) );
if ( ok )
Expand All @@ -462,6 +462,9 @@ QVariantMap QgsProcessingAlgorithm::run( const QVariantMap &parameters, QgsProce
}
catch ( QgsProcessingException &e )
{
if ( !catchExceptions )
throw e;

QgsMessageLog::logMessage( e.what(), QObject::tr( "Processing" ), Qgis::Critical );
feedback->reportError( e.what() );
return QVariantMap();
Expand Down
6 changes: 5 additions & 1 deletion src/core/processing/qgsprocessingalgorithm.h
Expand Up @@ -378,13 +378,17 @@ class CORE_EXPORT QgsProcessingAlgorithm
*
* If specified, \a ok will be set to TRUE if algorithm was successfully run.
*
* If \a catchExceptions is set to FALSE, then QgsProcessingExceptions raised during
* the algorithm run will not be automatically caught and will be raised instead.
*
* \returns A map of algorithm outputs. These may be output layer references, or calculated
* values such as statistical calculations.
*
* \note this method can only be called from the main thread. Use prepare(), runPrepared() and postProcess()
* if you need to run algorithms from a background thread, or use the QgsProcessingAlgRunnerTask class.
*/
QVariantMap run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok SIP_OUT = nullptr, const QVariantMap &configuration = QVariantMap() ) const;
QVariantMap run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback, bool *ok SIP_OUT = nullptr, const QVariantMap &configuration = QVariantMap(),
bool catchExceptions = true ) const SIP_THROW( QgsProcessingException );

/**
* Prepares the algorithm for execution. This must be run in the main thread, and allows the algorithm
Expand Down

0 comments on commit 2207c30

Please sign in to comment.