diff --git a/python/core/auto_generated/qgsvirtuallayertask.sip.in b/python/core/auto_generated/qgsvirtuallayertask.sip.in index e2569abb292..5d301b0dbdb 100644 --- a/python/core/auto_generated/qgsvirtuallayertask.sip.in +++ b/python/core/auto_generated/qgsvirtuallayertask.sip.in @@ -58,6 +58,20 @@ Reloads the data. %Docstring Cancels the pending query and the parent task. +%End + + QString exceptionText() const; +%Docstring +Return the exception text or an empty string if no exceptions were raised + +.. versionadded:: 3.4 +%End + + void setExceptionText( const QString &exceptionText ); +%Docstring +Sets the ``exceptionText`` + +.. versionadded:: 3.4 %End }; diff --git a/python/plugins/db_manager/db_plugins/plugin.py b/python/plugins/db_manager/db_plugins/plugin.py index ea11f07aefd..348a337bddb 100644 --- a/python/plugins/db_manager/db_plugins/plugin.py +++ b/python/plugins/db_manager/db_plugins/plugin.py @@ -50,9 +50,6 @@ class BaseError(Exception): def __unicode__(self): return self.msg - def __str__(self): - return str(self).encode('utf-8') - class InvalidDataException(BaseError): pass diff --git a/python/plugins/db_manager/db_plugins/vlayers/data_model.py b/python/plugins/db_manager/db_plugins/vlayers/data_model.py index 6d944e7457d..62880b9a3be 100644 --- a/python/plugins/db_manager/db_plugins/vlayers/data_model.py +++ b/python/plugins/db_manager/db_plugins/vlayers/data_model.py @@ -113,6 +113,8 @@ class LSqlResultModelAsync(SqlResultModelAsync): def modelDone(self): self.status = self.task.status self.model = self.task.model + if self.task.subtask.exceptionText(): + self.error = BaseError(self.task.subtask.exceptionText()) self.done.emit() diff --git a/src/core/qgsvirtuallayertask.cpp b/src/core/qgsvirtuallayertask.cpp index 54022783df3..5fb49f06a13 100644 --- a/src/core/qgsvirtuallayertask.cpp +++ b/src/core/qgsvirtuallayertask.cpp @@ -37,6 +37,7 @@ bool QgsVirtualLayerTask::run() catch ( std::exception &e ) { QgsDebugMsg( QStringLiteral( "Reload error: %1" ).arg( e.what() ) ); + setExceptionText( e.what() ); rc = false; } return rc; @@ -62,3 +63,13 @@ void QgsVirtualLayerTask::cancel() mLayer->dataProvider()->cancelReload(); QgsTask::cancel(); } + +QString QgsVirtualLayerTask::exceptionText() const +{ + return mExceptionText; +} + +void QgsVirtualLayerTask::setExceptionText( const QString &exceptionText ) +{ + mExceptionText = exceptionText; +} diff --git a/src/core/qgsvirtuallayertask.h b/src/core/qgsvirtuallayertask.h index a39ad4b2236..a3323e3f830 100644 --- a/src/core/qgsvirtuallayertask.h +++ b/src/core/qgsvirtuallayertask.h @@ -68,7 +68,20 @@ class CORE_EXPORT QgsVirtualLayerTask : public QgsTask */ void cancel() override; + /** + * Return the exception text or an empty string if no exceptions were raised + * \since QGIS 3.4 + */ + QString exceptionText() const; + + /** + * Sets the \a exceptionText + * \since QGIS 3.4 + */ + void setExceptionText( const QString &exceptionText ); + private: + QString mExceptionText; QgsVirtualLayerDefinition mDefinition; std::unique_ptr mLayer; }; diff --git a/tests/src/python/test_qgsvirtuallayertask.py b/tests/src/python/test_qgsvirtuallayertask.py index 7126e8a96e6..bd9f10319a7 100644 --- a/tests/src/python/test_qgsvirtuallayertask.py +++ b/tests/src/python/test_qgsvirtuallayertask.py @@ -33,17 +33,18 @@ class TestQgsVirtualLayerTask(unittest.TestCase): def setUp(self): self.testDataDir = unitTestDataPath() - self.success = False - self.fail = False + self._success = False + self._fail = False self.ids = None self.task = None def onSuccess(self): - self.success = True + self._success = True self.ids = [f.id() for f in self.task.layer().getFeatures()] def onFail(self): - self.fail = True + self._fail = True + self._exceptionText = self.task.exceptionText() def test(self): l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False)) @@ -61,14 +62,29 @@ class TestQgsVirtualLayerTask(unittest.TestCase): self.task.taskTerminated.connect(self.onFail) QgsApplication.taskManager().addTask(self.task) - while not self.success and not self.fail: + while not self._success and not self._fail: QCoreApplication.processEvents() - self.assertTrue(self.success) - self.assertFalse(self.fail) + self.assertTrue(self._success) + self.assertFalse(self._fail) self.assertEqual(len(self.ids), 4) + # Test exception + self._success = False + self._fail = False + df.setQuery('select *') + self.task = QgsVirtualLayerTask(df) + self.task.taskCompleted.connect(self.onSuccess) + self.task.taskTerminated.connect(self.onFail) + QgsApplication.taskManager().addTask(self.task) + while not self._success and not self._fail: + QCoreApplication.processEvents() + + self.assertFalse(self._success) + self.assertTrue(self._fail) + self.assertEqual(self._exceptionText, 'Query preparation error on PRAGMA table_info(_tview): no tables specified', self._exceptionText) + if __name__ == '__main__': unittest.main()