diff --git a/caravel/assets/javascripts/modules/caravel.js b/caravel/assets/javascripts/modules/caravel.js
index 26a784f3f57e5..9a8791994ba84 100644
--- a/caravel/assets/javascripts/modules/caravel.js
+++ b/caravel/assets/javascripts/modules/caravel.js
@@ -283,9 +283,27 @@ var px = (function () {
$('.query-and-save button').removeAttr('disabled');
always(data);
},
- error: function (msg) {
+ getErrorMsg: function (xhr) {
+ if (xhr.statusText === "timeout") {
+ return "The request timed out";
+ }
+ var msg = "";
+ if (!xhr.responseText) {
+ var status = xhr.status;
+ msg += "An unknown error occurred. (Status: " + status + ")";
+ if (status === 0) {
+ // This may happen when the worker in gunicorn times out
+ msg += " Maybe the request timed out?";
+ }
+ }
+ return msg;
+ },
+ error: function (msg, xhr) {
token.find("img.loading").hide();
- var err = '
' + msg + '
';
+ var err = msg ? ('' + msg + '
') : "";
+ if (xhr) {
+ err += '' + this.getErrorMsg(xhr) + '
';
+ }
container.html(err);
container.show();
$('span.query').removeClass('disabled');
diff --git a/caravel/assets/visualizations/big_number.js b/caravel/assets/visualizations/big_number.js
index 7351100924f71..42bec76202983 100644
--- a/caravel/assets/visualizations/big_number.js
+++ b/caravel/assets/visualizations/big_number.js
@@ -13,7 +13,7 @@ function bigNumberVis(slice) {
d3.json(slice.jsonEndpoint(), function (error, payload) {
//Define the percentage bounds that define color from red to green
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
div.html(''); //reset
diff --git a/caravel/assets/visualizations/cal_heatmap.js b/caravel/assets/visualizations/cal_heatmap.js
index d762cee8de8e4..8629a4e550267 100644
--- a/caravel/assets/visualizations/cal_heatmap.js
+++ b/caravel/assets/visualizations/cal_heatmap.js
@@ -16,7 +16,7 @@ function calHeatmap(slice) {
d3.json(slice.jsonEndpoint(), function (error, json) {
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
diff --git a/caravel/assets/visualizations/directed_force.js b/caravel/assets/visualizations/directed_force.js
index c9739d29c6d4f..e6ca616b7737f 100644
--- a/caravel/assets/visualizations/directed_force.js
+++ b/caravel/assets/visualizations/directed_force.js
@@ -16,7 +16,7 @@ function directedForceVis(slice) {
var charge = json.form_data.charge || -500;
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
var links = json.data;
diff --git a/caravel/assets/visualizations/filter_box.js b/caravel/assets/visualizations/filter_box.js
index df6cf99b15431..754216d0e6dc1 100644
--- a/caravel/assets/visualizations/filter_box.js
+++ b/caravel/assets/visualizations/filter_box.js
@@ -70,7 +70,7 @@ function filterBox(slice) {
}
})
.fail(function (xhr) {
- slice.error(xhr.responseText);
+ slice.error(xhr.responseText, xhr);
});
};
return {
diff --git a/caravel/assets/visualizations/heatmap.js b/caravel/assets/visualizations/heatmap.js
index a063f0be4b718..35cd727258324 100644
--- a/caravel/assets/visualizations/heatmap.js
+++ b/caravel/assets/visualizations/heatmap.js
@@ -24,7 +24,7 @@ function heatmapVis(slice) {
slice.container.html('');
var matrix = {};
if (error) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
var fd = payload.form_data;
diff --git a/caravel/assets/visualizations/horizon.js b/caravel/assets/visualizations/horizon.js
index 23dc02aaaf0db..0fefed31c010f 100644
--- a/caravel/assets/visualizations/horizon.js
+++ b/caravel/assets/visualizations/horizon.js
@@ -190,7 +190,7 @@ function horizonViz(slice) {
d3.json(slice.jsonEndpoint(), function (error, payload) {
var fd = payload.form_data;
if (error) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
diff --git a/caravel/assets/visualizations/iframe.js b/caravel/assets/visualizations/iframe.js
index d7c87aade753e..a32f475c31d7b 100644
--- a/caravel/assets/visualizations/iframe.js
+++ b/caravel/assets/visualizations/iframe.js
@@ -13,7 +13,7 @@ function iframeWidget(slice) {
slice.done(payload);
})
.fail(function (xhr) {
- slice.error(xhr.responseText);
+ slice.error(xhr.responseText, xhr);
});
}
diff --git a/caravel/assets/visualizations/markup.js b/caravel/assets/visualizations/markup.js
index 832e938df1637..2598831d77eef 100644
--- a/caravel/assets/visualizations/markup.js
+++ b/caravel/assets/visualizations/markup.js
@@ -10,7 +10,7 @@ function markupWidget(slice) {
slice.done(payload);
})
.fail(function (xhr) {
- slice.error(xhr.responseText);
+ slice.error(xhr.responseText, xhr);
});
}
diff --git a/caravel/assets/visualizations/nvd3_vis.js b/caravel/assets/visualizations/nvd3_vis.js
index 8c9bee9688829..143b4feac623e 100644
--- a/caravel/assets/visualizations/nvd3_vis.js
+++ b/caravel/assets/visualizations/nvd3_vis.js
@@ -15,6 +15,13 @@ function nvd3Vis(slice) {
var render = function () {
d3.json(slice.jsonEndpoint(), function (error, payload) {
+ slice.container.html('');
+ // Check error first, otherwise payload can be null
+ if (error) {
+ slice.error(error.responseText, error);
+ return '';
+ }
+
var width = slice.width();
var fd = payload.form_data;
var barchartWidth = function () {
@@ -30,15 +37,6 @@ function nvd3Vis(slice) {
return width;
}
};
- slice.container.html('');
- if (error) {
- if (error.responseText) {
- slice.error(error.responseText);
- } else {
- slice.error(error);
- }
- return '';
- }
var viz_type = fd.viz_type;
var f = d3.format('.3s');
var reduceXTicks = fd.reduce_x_ticks || false;
diff --git a/caravel/assets/visualizations/parallel_coordinates.js b/caravel/assets/visualizations/parallel_coordinates.js
index 1cd501074726f..7cd2da83f36e9 100644
--- a/caravel/assets/visualizations/parallel_coordinates.js
+++ b/caravel/assets/visualizations/parallel_coordinates.js
@@ -95,7 +95,7 @@ function parallelCoordVis(slice) {
slice.done(payload);
})
.fail(function (xhr) {
- slice.error(xhr.responseText);
+ slice.error(xhr.responseText, xhr);
});
}
diff --git a/caravel/assets/visualizations/pivot_table.js b/caravel/assets/visualizations/pivot_table.js
index 208a03cf10605..fa1fc8aa3ee0f 100644
--- a/caravel/assets/visualizations/pivot_table.js
+++ b/caravel/assets/visualizations/pivot_table.js
@@ -22,7 +22,7 @@ module.exports = function (slice) {
}
slice.done(json);
}).fail(function (xhr) {
- slice.error(xhr.responseText);
+ slice.error(xhr.responseText, xhr);
});
}
return {
diff --git a/caravel/assets/visualizations/sankey.js b/caravel/assets/visualizations/sankey.js
index 08bc3af892662..80134fb7f1652 100644
--- a/caravel/assets/visualizations/sankey.js
+++ b/caravel/assets/visualizations/sankey.js
@@ -40,7 +40,7 @@ function sankeyVis(slice) {
d3.json(slice.jsonEndpoint(), function (error, json) {
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
var links = json.data;
diff --git a/caravel/assets/visualizations/sunburst.js b/caravel/assets/visualizations/sunburst.js
index ccf3b917a155f..4ee911a068e8e 100644
--- a/caravel/assets/visualizations/sunburst.js
+++ b/caravel/assets/visualizations/sunburst.js
@@ -54,7 +54,7 @@ function sunburstVis(slice) {
d3.json(slice.jsonEndpoint(), function (error, rawData) {
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
createBreadcrumbs(rawData);
diff --git a/caravel/assets/visualizations/table.js b/caravel/assets/visualizations/table.js
index 254dca7106c73..53a07fca14d82 100644
--- a/caravel/assets/visualizations/table.js
+++ b/caravel/assets/visualizations/table.js
@@ -16,7 +16,7 @@ function tableVis(slice) {
$.getJSON(slice.jsonEndpoint(), onSuccess).fail(onError);
function onError(xhr) {
- slice.error(xhr.responseText);
+ slice.error(xhr.responseText, xhr);
}
function onSuccess(json) {
diff --git a/caravel/assets/visualizations/treemap.js b/caravel/assets/visualizations/treemap.js
index 680d3d4f0181f..7cc297729fb27 100644
--- a/caravel/assets/visualizations/treemap.js
+++ b/caravel/assets/visualizations/treemap.js
@@ -231,7 +231,7 @@ function treemap(slice) {
d3.json(slice.jsonEndpoint(), function (error, json) {
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
diff --git a/caravel/assets/visualizations/word_cloud.js b/caravel/assets/visualizations/word_cloud.js
index 7efd7c03193c7..6a5e23fefc80d 100644
--- a/caravel/assets/visualizations/word_cloud.js
+++ b/caravel/assets/visualizations/word_cloud.js
@@ -8,7 +8,7 @@ function wordCloudChart(slice) {
function refresh() {
d3.json(slice.jsonEndpoint(), function (error, json) {
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
var data = json.data;
diff --git a/caravel/assets/visualizations/world_map.js b/caravel/assets/visualizations/world_map.js
index 76c991d3a247c..57471c5607990 100644
--- a/caravel/assets/visualizations/world_map.js
+++ b/caravel/assets/visualizations/world_map.js
@@ -18,7 +18,7 @@ function worldMapChart(slice) {
var fd = json.form_data;
if (error !== null) {
- slice.error(error.responseText);
+ slice.error(error.responseText, error);
return '';
}
var ext = d3.extent(json.data, function (d) {