mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-09 00:08:52 -04:00
[processing] Fix GDAL algorithms hang when gdal command is not available to run
This commit is contained in:
parent
14e5c6094d
commit
af0fb8bb87
@ -129,6 +129,13 @@ After execution completes, the process' result code will be returned.
|
|||||||
QProcess::ExitStatus exitStatus() const;
|
QProcess::ExitStatus exitStatus() const;
|
||||||
%Docstring
|
%Docstring
|
||||||
After a call to :py:func:`~QgsBlockingProcess.run`, returns the process' exit status.
|
After a call to :py:func:`~QgsBlockingProcess.run`, returns the process' exit status.
|
||||||
|
%End
|
||||||
|
|
||||||
|
QProcess::ProcessError processError() const;
|
||||||
|
%Docstring
|
||||||
|
After a call to :py:func:`~QgsBlockingProcess.run`, returns the process' reported error.
|
||||||
|
|
||||||
|
Returns QProcess.UnknownError if no error occurred.
|
||||||
%End
|
%End
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -150,6 +150,8 @@ class GdalUtils:
|
|||||||
raise QgsProcessingException(GdalUtils.tr('Process was unexpectedly terminated'))
|
raise QgsProcessingException(GdalUtils.tr('Process was unexpectedly terminated'))
|
||||||
elif res == 0:
|
elif res == 0:
|
||||||
feedback.pushInfo(GdalUtils.tr('Process completed successfully'))
|
feedback.pushInfo(GdalUtils.tr('Process completed successfully'))
|
||||||
|
elif proc.processError() == QProcess.FailedToStart:
|
||||||
|
raise QgsProcessingException(GdalUtils.tr('Process {} failed to start. Either {} is missing, or you may have insufficient permissions to run the program.').format(command, command))
|
||||||
else:
|
else:
|
||||||
feedback.reportError(GdalUtils.tr('Process returned error code {}').format(res))
|
feedback.reportError(GdalUtils.tr('Process returned error code {}').format(res))
|
||||||
|
|
||||||
|
@ -272,8 +272,9 @@ int QgsBlockingProcess::run( QgsFeedback *feedback )
|
|||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
QProcess::ExitStatus exitStatus = QProcess::NormalExit;
|
QProcess::ExitStatus exitStatus = QProcess::NormalExit;
|
||||||
|
QProcess::ProcessError error = QProcess::UnknownError;
|
||||||
|
|
||||||
std::function<void()> runFunction = [ this, &result, &exitStatus, feedback]()
|
std::function<void()> runFunction = [ this, &result, &exitStatus, &error, feedback]()
|
||||||
{
|
{
|
||||||
// this function will always be run in worker threads -- either the blocking call is being made in a worker thread,
|
// this function will always be run in worker threads -- either the blocking call is being made in a worker thread,
|
||||||
// or the blocking call has been made from the main thread and we've fired up a new thread for this function
|
// or the blocking call has been made from the main thread and we've fired up a new thread for this function
|
||||||
@ -319,8 +320,16 @@ int QgsBlockingProcess::run( QgsFeedback *feedback )
|
|||||||
mStderrHandler( ba );
|
mStderrHandler( ba );
|
||||||
} );
|
} );
|
||||||
p.start( mProcess, mArguments, QProcess::Unbuffered | QProcess::ReadWrite );
|
p.start( mProcess, mArguments, QProcess::Unbuffered | QProcess::ReadWrite );
|
||||||
|
if ( !p.waitForStarted() )
|
||||||
loop.exec();
|
{
|
||||||
|
result = 1;
|
||||||
|
exitStatus = QProcess::NormalExit;
|
||||||
|
error = p.error();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loop.exec();
|
||||||
|
}
|
||||||
|
|
||||||
mStdoutHandler( p.readAllStandardOutput() );
|
mStdoutHandler( p.readAllStandardOutput() );
|
||||||
mStderrHandler( p.readAllStandardError() );
|
mStderrHandler( p.readAllStandardError() );
|
||||||
@ -339,6 +348,7 @@ int QgsBlockingProcess::run( QgsFeedback *feedback )
|
|||||||
}
|
}
|
||||||
|
|
||||||
mExitStatus = exitStatus;
|
mExitStatus = exitStatus;
|
||||||
|
mProcessError = error;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,4 +356,9 @@ QProcess::ExitStatus QgsBlockingProcess::exitStatus() const
|
|||||||
{
|
{
|
||||||
return mExitStatus;
|
return mExitStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QProcess::ProcessError QgsBlockingProcess::processError() const
|
||||||
|
{
|
||||||
|
return mProcessError;
|
||||||
|
};
|
||||||
#endif // QT_CONFIG(process)
|
#endif // QT_CONFIG(process)
|
||||||
|
@ -185,6 +185,13 @@ class CORE_EXPORT QgsBlockingProcess : public QObject
|
|||||||
*/
|
*/
|
||||||
QProcess::ExitStatus exitStatus() const;
|
QProcess::ExitStatus exitStatus() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After a call to run(), returns the process' reported error.
|
||||||
|
*
|
||||||
|
* Returns QProcess::UnknownError if no error occurred.
|
||||||
|
*/
|
||||||
|
QProcess::ProcessError processError() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QString mProcess;
|
QString mProcess;
|
||||||
@ -193,6 +200,7 @@ class CORE_EXPORT QgsBlockingProcess : public QObject
|
|||||||
std::function< void( const QByteArray & ) > mStderrHandler;
|
std::function< void( const QByteArray & ) > mStderrHandler;
|
||||||
|
|
||||||
QProcess::ExitStatus mExitStatus = QProcess::NormalExit;
|
QProcess::ExitStatus mExitStatus = QProcess::NormalExit;
|
||||||
|
QProcess::ProcessError mProcessError = QProcess::UnknownError;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QT_CONFIG(process)
|
#endif // QT_CONFIG(process)
|
||||||
|
@ -113,6 +113,31 @@ class TestQgsBlockingProcess(unittest.TestCase):
|
|||||||
self.assertNotEqual(p.run(f), 0)
|
self.assertNotEqual(p.run(f), 0)
|
||||||
self.assertEqual(p.exitStatus(), QProcess.CrashExit)
|
self.assertEqual(p.exitStatus(), QProcess.CrashExit)
|
||||||
|
|
||||||
|
def test_process_no_file(self):
|
||||||
|
"""
|
||||||
|
Test a script which doesn't exist
|
||||||
|
"""
|
||||||
|
|
||||||
|
def std_out(ba):
|
||||||
|
std_out.val += ba.data().decode('UTF-8')
|
||||||
|
|
||||||
|
std_out.val = ''
|
||||||
|
|
||||||
|
def std_err(ba):
|
||||||
|
std_err.val += ba.data().decode('UTF-8')
|
||||||
|
|
||||||
|
std_err.val = ''
|
||||||
|
|
||||||
|
# this program definitely doesn't exist!
|
||||||
|
p = QgsBlockingProcess('qgis_sucks', ['--version'])
|
||||||
|
p.setStdOutHandler(std_out)
|
||||||
|
p.setStdErrHandler(std_err)
|
||||||
|
|
||||||
|
f = QgsFeedback()
|
||||||
|
self.assertEqual(p.run(f), 1)
|
||||||
|
self.assertEqual(p.exitStatus(), QProcess.NormalExit)
|
||||||
|
self.assertEqual(p.processError(), QProcess.FailedToStart)
|
||||||
|
|
||||||
def test_process_env(self):
|
def test_process_env(self):
|
||||||
"""
|
"""
|
||||||
Test that process inherits system environment correctly
|
Test that process inherits system environment correctly
|
||||||
|
Loading…
x
Reference in New Issue
Block a user