[db-manager] Store exception text in the task and pass it over to the caller

Fix #2019 - DBManager fails to display error messages with virtual layers
This commit is contained in:
Alessandro Pasotti 2018-10-23 14:59:10 +02:00
parent 5e6eef3e54
commit 15f4138a47
6 changed files with 63 additions and 10 deletions

View File

@ -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
};

View File

@ -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

View File

@ -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()

View File

@ -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;
}

View File

@ -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<QgsVectorLayer> mLayer;
};

View File

@ -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()