From d42aed093571fc0d5fdaa1c00967d36d707c1140 Mon Sep 17 00:00:00 2001 From: Tim Buckley Date: Wed, 27 Jan 2016 16:54:38 -0700 Subject: [PATCH] Improve handling of dstat load failures. This tweaks how Dstat data is loaded to handle errors more cleanly. Attempts to load dstat data for datasets that don't have it configured will fail early and avoid making a request, and 404 errors are now handled appropriately. Also, the Dstat parser now validates headers to make sure it is actually parsing Dstat CSV data. Lastly, the chart is now hidden until data is loaded successfully, removing the large blank area previously shown for missing datasets. Change-Id: I96b8d038af1cc718ae9c43a078679a04533fddc5 --- app/js/directives/timeline-dstat.js | 5 ++++- app/js/directives/timeline.js | 6 +++--- app/js/services/dataset.js | 15 +++++++++++---- app/js/util/dstat-parse.js | 8 +++++++- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/app/js/directives/timeline-dstat.js b/app/js/directives/timeline-dstat.js index 5b8ef35..8368ad7 100644 --- a/app/js/directives/timeline-dstat.js +++ b/app/js/directives/timeline-dstat.js @@ -85,7 +85,8 @@ function timelineDstat() { var chart = d3.select(el[0]) .append('svg') .attr('width', timelineController.width + margin.left + margin.right) - .attr('height', height); + .attr('height', height) + .style('display', 'none'); var main = chart.append('g') .attr('transform', 'translate(' + margin.left + ',0)'); @@ -177,6 +178,8 @@ function timelineDstat() { y.domain([0, lanes.length]).range([0, height]); lanes.forEach(initLane); + + chart.style('display', 'block'); }); scope.$on('update', function() { diff --git a/app/js/directives/timeline.js b/app/js/directives/timeline.js index a730f9c..bac10e8 100644 --- a/app/js/directives/timeline.js +++ b/app/js/directives/timeline.js @@ -252,11 +252,11 @@ function timeline($log, datasetService, progressService) { var raw = parseDstat(response.data, firstDate.getYear()); initDstat(raw); - + }).catch(function(ex) { + $log.warn(ex); + }).finally(function() { $scope.$broadcast('update'); progressService.done(); - }).catch(function(ex) { - $log.error(ex); }); }); diff --git a/app/js/services/dataset.js b/app/js/services/dataset.js index 42be478..72af04a 100644 --- a/app/js/services/dataset.js +++ b/app/js/services/dataset.js @@ -59,10 +59,17 @@ function DatasetService($q, $http) { }; service.dstat = function(dataset) { - return $http({ - cache: true, - url: "data/" + dataset.dstat, - method: 'GET' + return $q(function(resolve, reject) { + if (!dataset.dstat) { + reject({ status: -1, statusText: 'Dstat not available for dataset.' }); + return; + } + + resolve($http({ + cache: true, + url: "data/" + dataset.dstat, + method: 'GET' + })); }); }; diff --git a/app/js/util/dstat-parse.js b/app/js/util/dstat-parse.js index 194bc95..2707722 100644 --- a/app/js/util/dstat-parse.js +++ b/app/js/util/dstat-parse.js @@ -41,7 +41,13 @@ var parseDstat = function(data, year) { var dateFormat = d3.time.format.utc("%d-%m %H:%M:%S"); var parsed = d3.csv.parseRows(data, function(row, i) { - if (i <= 4) { // header rows - ignore + if (i === 0) { + if (row.length !== 1 || + !row[0].startsWith('Dstat') || + !row[0].endsWith('CSV output')) { + throw new Error('Invalid Dstat CSV'); + } + } else if (i <= 4) { // header rows - ignore return null; } else if (i === 5) { // primary primaryNames = row;