Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #10701 enabling failures for wms requests with exception, for ImageWMS sources #10702

Merged
merged 6 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions web/client/components/map/openlayers/__tests__/Layer-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,37 @@ describe('Openlayers layer', () => {
expect(layer).toBeTruthy();
expect(map.getLayers().getLength()).toBe(1);
});
it('render wms singleTile layer with error', (done) => {
mockAxios.onGet().reply(r => {
expect(r.url.indexOf('SAMPLE_URL') >= 0 ).toBeTruthy();
return [200, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<ows:ExceptionReport xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
" <ows:Exception exceptionCode=\"InvalidParameterValue\" locator=\"srsname\">\n" +
" <ows:ExceptionText>msWFSGetFeature(): WFS server error. Invalid GetFeature Request</ows:ExceptionText>\n" +
" </ows:Exception>\n" +
"</ows:ExceptionReport>"];
});
const options = {
type: 'wms',
visibility: true,
singleTile: true,
url: 'SAMPLE_URL',
name: 'osm:vector_tile'
};
const layer = ReactDOM.render(<OpenlayersLayer
type="wms"
options={{
...options
}}
map={map} />, document.getElementById("container"));
expect(layer.layer.getSource()).toBeTruthy();
layer.layer.getSource().on('imageloaderror', (e)=> {
setTimeout(() => {
expect(e).toBeTruthy();
done();
}, 200);
});
});
it('creates a tiled wms layer for openlayers map with long url', (done) => {
let options = {
"type": "wms",
Expand Down
9 changes: 7 additions & 2 deletions web/client/components/map/openlayers/plugins/WMSLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import VectorTileSource from 'ol/source/VectorTile';
import VectorTileLayer from 'ol/layer/VectorTile';

import { isVectorFormat } from '../../../../utils/VectorTileUtils';
import { isValidResponse } from '../../../../utils/WMSUtils';
import { OL_VECTOR_FORMATS, applyStyle } from '../../../../utils/openlayers/VectorTileUtils';

import { proxySource, getWMSURLs, wmsToOpenlayersOptions, toOLAttributions, generateTileGrid } from '../../../../utils/openlayers/WMSUtils';
Expand Down Expand Up @@ -74,10 +75,14 @@ const loadFunction = (options, headers) => function(image, src) {
headers,
responseType: 'blob'
}).then(response => {
if (response.status === 200 && response.data) {
if (isValidResponse(response)) {
image.getImage().src = URL.createObjectURL(response.data);
} else {
console.error("Status code: " + response.status);
// #10701 this is needed to trigger the imageloaderror event
// in ol otherwise this event is not triggered if you assign
// the xml content of the exception to the src attribute
image.getImage().src = null;
console.error("error: " + response.data);
}
}).catch(e => {
console.error(e);
Expand Down
13 changes: 13 additions & 0 deletions web/client/utils/WMSUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ export const isValidGetMapFormat = (format) => {
export const isValidGetFeatureInfoFormat = (format) => {
return getDefaultSupportedGetFeatureInfoFormats().includes(format);
};

/**
* Validate GetMap response from WMS ImageWMS.
* "OGC protocol returns status = 200 with Exception in body,
* this function checks if the exception is contained in the response".
* https://docs.geoserver.org/main/en/user/services/wms/reference.html#exceptions
* @param {object} response
* @return {boolean}
*/
export const isValidResponse = (response) => {
return response?.status === 200 && response?.data && response?.data?.type !== "text/xml";
};

/**
* Parses layer info from capabilities object
* @param {object} capabilities capabilities section of the layer as an object from xml2js parsing of the WMS capabilities
Expand Down
11 changes: 10 additions & 1 deletion web/client/utils/__tests__/WMSUtils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
isValidGetFeatureInfoFormat,
getLayerOptions,
getTileGridFromLayerOptions,
getCustomTileGridProperties
getCustomTileGridProperties,
isValidResponse
} from '../WMSUtils';

describe('Test the WMSUtils', () => {
Expand Down Expand Up @@ -96,4 +97,12 @@ describe('Test the WMSUtils', () => {
}
});
});
it('test isValidResponse', () => {
// invalid responses
expect(isValidResponse({data: {type: "text/xml"}})).toBeFalsy();
expect(isValidResponse({data: {type: "blob"}})).toBeFalsy();
expect(isValidResponse({data: {type: "blob"}, status: 401})).toBeFalsy();
// valid responses
expect(isValidResponse({data: {type: "blob"}, status: 200})).toBeTruthy();
});
});
Loading