Skip to content

Commit

Permalink
[WFS provider] Parse WMS service exceptions (fixes #29866)
Browse files Browse the repository at this point in the history
(cherry picked from commit 63c34e3)
  • Loading branch information
rouault authored and nyalldawson committed Jun 19, 2020
1 parent e43eb10 commit 1e62347
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/providers/wfs/qgswfscapabilities.cpp
Expand Up @@ -167,15 +167,28 @@ void QgsWfsCapabilities::capabilitiesReplyFinished()
// handle exceptions
if ( doc.tagName() == QLatin1String( "ExceptionReport" ) )
{
QDomNode ex = doc.firstChild();
QDomNode ex = doc.firstChild(); // Get Exception element
QString exc = ex.toElement().attribute( QStringLiteral( "exceptionCode" ), QStringLiteral( "Exception" ) );
QDomElement ext = ex.firstChild().toElement();
QDomElement ext = ex.firstChild().toElement(); // Get ExceptionText element
mErrorCode = QgsWfsRequest::ServerExceptionError;
mErrorMessage = exc + ": " + ext.firstChild().nodeValue();
emit gotCapabilities();
return;
}

// handle WMS exceptions as well (to be nice with users...)
// See https://github.com/qgis/QGIS/issues/29866
if ( doc.tagName() == QLatin1String( "ServiceExceptionReport" ) )
{
QDomNode ex = doc.firstChild(); // Get ServiceExceptionReport element
QString exc = ex.toElement().attribute( QStringLiteral( "code" ), QStringLiteral( "Exception" ) );
QDomElement ext = ex.toElement();
mErrorCode = QgsWfsRequest::ServerExceptionError;
mErrorMessage = exc + ": " + ext.firstChild().nodeValue().trimmed();
emit gotCapabilities();
return;
}

mCaps.clear();

//test wfs version
Expand Down
52 changes: 52 additions & 0 deletions tests/src/python/test_provider_wfs.py
Expand Up @@ -4339,6 +4339,58 @@ def testWFS20CaseInsensitiveKVP(self):
vl_extent = QgsGeometry.fromRect(vl.extent())
assert QgsGeometry.compare(vl_extent.asPolygon()[0], reference.asPolygon()[0], 0.00001), 'Expected {}, got {}'.format(reference.asWkt(), vl_extent.asWkt())

def testGetCapabilitiesReturnWFSException(self):
"""Test parsing of WFS exception
"""
endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_testGetCapabilitiesReturnWFSException'

get_cap_response = """<?xml version="1.0" encoding="UTF-8"?>
<ExceptionReport xmlns="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd" version="1.0.0" language="en">
<Exception exceptionCode="foo" locator="service">
<ExceptionText>bar</ExceptionText>
</Exception>
</ExceptionReport>
""".encode('UTF-8')

with open(sanitize(endpoint,
'?SERVICE=WFS&REQUEST=GetCapabilities&VERSION=1.0.0'),
'wb') as f:
f.write(get_cap_response)

with MessageLogger('WFS') as logger:
vl = QgsVectorLayer("url='http://" + endpoint + "' typename='my:typename' version='1.0.0'", 'test', 'WFS')
self.assertFalse(vl.isValid())

self.assertEqual(len(logger.messages()), 1, logger.messages())
self.assertTrue("foo: bar" in logger.messages()[0].decode('UTF-8'), logger.messages())

def testGetCapabilitiesReturnWMSException(self):
"""Test fix for https://github.com/qgis/QGIS/issues/29866
"""
endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_testGetCapabilitiesReturnWMSxception'

get_cap_response = """<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE ServiceExceptionReport SYSTEM "http://schemas.opengis.net/wms/1.1.1/exception_1_1_1.dtd">
<ServiceExceptionReport version="1.1.1">
<ServiceException code="InvalidFormat">
Can't recognize service requested.
</ServiceException>
</ServiceExceptionReport>
""".encode('UTF-8')

with open(sanitize(endpoint,
'?SERVICE=WFS&REQUEST=GetCapabilities&VERSION=1.0.0'),
'wb') as f:
f.write(get_cap_response)

with MessageLogger('WFS') as logger:
vl = QgsVectorLayer("url='http://" + endpoint + "' typename='my:typename' version='1.0.0'", 'test', 'WFS')
self.assertFalse(vl.isValid())

self.assertEqual(len(logger.messages()), 1, logger.messages())
self.assertTrue("InvalidFormat: Can't recognize service requested." in logger.messages()[0].decode('UTF-8'), logger.messages())


if __name__ == '__main__':
unittest.main()

0 comments on commit 1e62347

Please sign in to comment.