diff --git a/src/ol/source/tilejsonsource.js b/src/ol/source/tilejsonsource.js index 09a991e5c3..637548ece0 100644 --- a/src/ol/source/tilejsonsource.js +++ b/src/ol/source/tilejsonsource.js @@ -44,23 +44,47 @@ ol.source.TileJSON = function(options) { ol.net.jsonp(options.url, this.handleTileJSONResponse.bind(this), this.handleTileJSONError.bind(this)); } else { - var xhr = new XMLHttpRequest(); - xhr.open('GET', options.url, true); - xhr.onload = function(e) { - if (xhr.status >= 200 && xhr.status < 300) { - var response = /** @type {TileJSON} */(JSON.parse(xhr.responseText)); - this.handleTileJSONResponse(response); - } else { - this.handleTileJSONError(); - } - }.bind(this); - xhr.send(); + var client = new XMLHttpRequest(); + client.addEventListener('load', this.onXHRLoad_.bind(this)); + client.addEventListener('error', this.onXHRError_.bind(this)); + client.open('GET', options.url); + client.send(); } }; goog.inherits(ol.source.TileJSON, ol.source.TileImage); +/** + * @private + * @param {Event} event The load event. + */ +ol.source.TileJSON.prototype.onXHRLoad_ = function(event) { + var client = /** @type {XMLHttpRequest} */ (event.target); + if (client.status >= 200 && client.status < 300) { + var response; + try { + response = /** @type {TileJSON} */(JSON.parse(client.responseText)); + } catch (err) { + this.handleTileJSONError(); + return; + } + this.handleTileJSONResponse(response); + } else { + this.handleTileJSONError(); + } +}; + + +/** + * @private + * @param {Event} event The error event. + */ +ol.source.TileJSON.prototype.onXHRError_ = function(event) { + this.handleTileJSONError(); +}; + + /** * @protected * @param {TileJSON} tileJSON Tile JSON. diff --git a/test/spec/ol/source/tilejsonsource.test.js b/test/spec/ol/source/tilejsonsource.test.js index b21d5b2d86..202371067e 100644 --- a/test/spec/ol/source/tilejsonsource.test.js +++ b/test/spec/ol/source/tilejsonsource.test.js @@ -4,14 +4,32 @@ goog.provide('ol.test.source.TileJSON'); describe('ol.source.TileJSON', function() { describe('#getState', function() { + it('returns ol.source.State.ERROR on HTTP 404', function() { - var changeSpy = sinon.spy(function(event) { - expect(event.target.getState()).to.eql('error'); - }); var source = new ol.source.TileJSON({ url: 'invalid.jsonp' }); - ol.events.listen(source, 'change', changeSpy); + source.on('change', function() { + expect(source.getState()).to.eql('error'); + }); + }); + + it('returns ol.source.State.ERROR on CORS issues', function() { + var source = new ol.source.TileJSON({ + url: 'http://example.com' + }); + source.on('change', function() { + expect(source.getState()).to.eql('error'); + }); + }); + + it('returns ol.source.State.ERROR on JSON parsing issues', function() { + var source = new ol.source.TileJSON({ + url: '/' + }); + source.on('change', function() { + expect(source.getState()).to.eql('error'); + }); }); });