diff --git a/lib/cartodb/models/analysis-mapconfig-adapter.js b/lib/cartodb/models/analysis-mapconfig-adapter.js index d2bf15bf..b2640101 100644 --- a/lib/cartodb/models/analysis-mapconfig-adapter.js +++ b/lib/cartodb/models/analysis-mapconfig-adapter.js @@ -132,16 +132,29 @@ AnalysisMapConfigAdapter.prototype.getMapConfig = function(analysisConfiguration return sourceId2Query; }, {}); - requestMapConfig.layers = requestMapConfig.layers.map(function(layer) { + var missingNodesErrors = []; + + requestMapConfig.layers = requestMapConfig.layers.map(function(layer, layerIndex) { if (layer.options.source && layer.options.source.id) { - var layerNode = sourceId2Node[layer.options.source.id]; - layer.options.sql = layerQuery(layerNode.getQuery(), layerNode.getColumns()); + var layerSourceId = layer.options.source.id; + var layerNode = sourceId2Node[layerSourceId]; + if (layerNode) { + layer.options.sql = layerQuery(layerNode.getQuery(), layerNode.getColumns()); + } else { + missingNodesErrors.push( + new Error('Missing analysis node.id="' + layerSourceId +'" for layer='+layerIndex) + ); + } } return layer; }); debug('mapconfig output', JSON.stringify(requestMapConfig, null, 4)); + if (missingNodesErrors.length > 0) { + return callback(missingNodesErrors); + } + return callback(null, requestMapConfig, analysesResults); }); }; diff --git a/test/acceptance/analysis/error-cases.js b/test/acceptance/analysis/error-cases.js new file mode 100644 index 00000000..a2e9db65 --- /dev/null +++ b/test/acceptance/analysis/error-cases.js @@ -0,0 +1,77 @@ +require('../../support/test_helper'); + +var assert = require('../../support/assert'); +var TestClient = require('../../support/test-client'); + +describe('analysis-layers error cases', function() { + function mapConfig(layers, dataviews, analysis) { + return { + version: '1.5.0', + layers: layers, + dataviews: dataviews || {}, + analyses: analysis || [] + }; + } + + var useCases = [ + { + desc: 'invalid source.id in layer', + fixture: 'buffer-over-source.png', + tile: { z: 7, x: 61, y: 47 }, + mapConfig: mapConfig( + [ + { + "type": "cartodb", + "options": { + "source": { + "id": "INVALID-SOURCE-ID" + }, + "cartocss": '#polygons { polygon-fill: red; }', + "cartocss_version": "2.3.0" + } + } + ], + {}, + [ + { + "id": "HEAD", + "type": "buffer", + "params": { + "source": { + "id": "2570e105-7b37-40d2-bdf4-1af889598745", + "type": "source", + "params": { + "query": "select * from populated_places_simple_reduced" + } + }, + "radius": 50000 + } + } + ] + ) + } + ]; + + var ERROR_RESPONSE = { + status: 400, + headers: { + 'Content-Type': 'application/json; charset=utf-8' + } + }; + + useCases.forEach(function(useCase) { + it('should implement use case: "' + useCase.desc + '"', function(done) { + + var testClient = new TestClient(useCase.mapConfig, 1234); + + testClient.getLayergroup(ERROR_RESPONSE, function(err, layergroupResult) { + assert.ok(!err, err); + + assert.equal(layergroupResult.errors.length, 1); + assert.equal(layergroupResult.errors[0], 'Missing analysis node.id="INVALID-SOURCE-ID" for layer=0'); + + testClient.drain(done); + }); + }); + }); +});