diff --git a/superset/assets/javascripts/SqlLab/actions.js b/superset/assets/javascripts/SqlLab/actions.js index 2e60a4c8ba8..0effacefcf1 100644 --- a/superset/assets/javascripts/SqlLab/actions.js +++ b/superset/assets/javascripts/SqlLab/actions.js @@ -151,6 +151,9 @@ export function runQuery(query) { } else if (msg === null) { msg = `[${textStatus}] ${errorThrown}`; } + if (msg.indexOf('The CSRF token is missing') > 0) { + msg = 'Your session timed out, please refresh your page and try again.'; + } dispatch(queryFailed(query, msg)); }, }); diff --git a/superset/assets/javascripts/SqlLab/components/ResultSet.jsx b/superset/assets/javascripts/SqlLab/components/ResultSet.jsx index f6661823fcc..bee97d61a27 100644 --- a/superset/assets/javascripts/SqlLab/components/ResultSet.jsx +++ b/superset/assets/javascripts/SqlLab/components/ResultSet.jsx @@ -38,6 +38,10 @@ export default class ResultSet extends React.PureComponent { height: props.search ? props.height - RESULT_SET_CONTROLS_HEIGHT : props.height, }; } + componentDidMount() { + // only do this the first time the component is rendered/mounted + this.reRunQueryIfSessionTimeoutErrorOnMount(); + } componentWillReceiveProps(nextProps) { // when new results comes in, save them locally and clear in store if (this.props.cache && (!nextProps.query.cached) @@ -53,7 +57,6 @@ export default class ResultSet extends React.PureComponent { this.fetchResults(nextProps.query); } } - getControls() { if (this.props.search || this.props.visualize || this.props.csv) { let csvButton; @@ -132,7 +135,12 @@ export default class ResultSet extends React.PureComponent { reFetchQueryResults(query) { this.props.actions.reFetchQueryResults(query); } - + reRunQueryIfSessionTimeoutErrorOnMount() { + const { query } = this.props; + if (query.errorMessage && query.errorMessage.indexOf('session timed out') > 0) { + this.props.actions.runQuery(query, true); + } + } render() { const query = this.props.query; const results = query.results;