[sqllab] async queries - better error handling (#1853)

This commit is contained in:
Maxime Beauchemin 2016-12-19 22:33:55 -08:00 committed by GitHub
parent 0712894353
commit 16731056ed
7 changed files with 26 additions and 17 deletions

View File

@ -85,8 +85,12 @@ export function fetchQueryResults(query) {
success(results) {
dispatch(querySuccess(query, results));
},
error() {
dispatch(queryFailed(query, 'Failed at retrieving results from the results backend'));
error(err) {
let msg = 'Failed at retrieving results from the results backend';
if (err.responseJSON && err.responseJSON.error) {
msg = err.responseJSON.error;
}
dispatch(queryFailed(query, msg));
},
});
};

View File

@ -1,5 +1,4 @@
import React from 'react';
import { Well } from 'react-bootstrap';
import SyntaxHighlighter from 'react-syntax-highlighter';
import { github } from 'react-syntax-highlighter/dist/styles';
import ModalTrigger from '../../components/ModalTrigger';
@ -45,11 +44,9 @@ class HighlightedSql extends React.Component {
const props = this.props;
let shownSql = props.shrink ? this.shrinkSql(props.sql) : props.sql;
return (
<Well>
<SyntaxHighlighter language="sql" style={github}>
{shownSql}
</SyntaxHighlighter>
</Well>);
<SyntaxHighlighter language="sql" style={github}>
{shownSql}
</SyntaxHighlighter>);
}
generateModal() {
const props = this.props;

View File

@ -2,7 +2,7 @@ import React from 'react';
import moment from 'moment';
import { Table } from 'reactable';
import { Label, ProgressBar } from 'react-bootstrap';
import { Label, ProgressBar, Well } from 'react-bootstrap';
import Link from './Link';
import VisualizeModal from './VisualizeModal';
import ResultSet from './ResultSet';
@ -107,7 +107,9 @@ class QueryTable extends React.PureComponent {
</div>
);
q.sql = (
<HighlightedSql sql={q.sql} rawSql={q.executedSql} shrink maxWidth={60} />
<Well>
<HighlightedSql sql={q.sql} rawSql={q.executedSql} shrink maxWidth={60} />
</Well>
);
if (q.resultsKey) {
q.output = (

View File

@ -220,7 +220,7 @@ class ResultSet extends React.PureComponent {
</Button>
);
}
return (<Alert bsStyle="warning">The query returned no data</Alert>);
return <Alert bsStyle="warning">The query returned no data</Alert>;
}
}
ResultSet.propTypes = propTypes;

View File

@ -24,9 +24,9 @@ describe('HighlightedSql', () => {
it('renders two SyntaxHighlighter in modal', () => {
const wrapper = mount(
<HighlightedSql sql={sql} rawSql="SELECT * FORM foo" shrink maxWidth={5} />);
const well = wrapper.find('.well');
expect(well).to.have.length(1);
well.simulate('click');
const pre = wrapper.find('pre');
expect(pre).to.have.length(1);
pre.simulate('click');
const modalBody = mount(wrapper.state().modalBody);
expect(modalBody.find(SyntaxHighlighter)).to.have.length(2);
});

View File

@ -87,6 +87,9 @@ def get_sql_results(self, query_id, return_results=True, store_results=False):
session.commit()
raise Exception(query.error_message)
if store_results and not results_backend:
handle_error("Results backend isn't configured.")
# Limit enforced only for retrieving the data, not for the CTA queries.
superset_query = sql_parse.SupersetQuery(executed_sql)
if not superset_query.is_select() and not database.allow_dml:
@ -169,7 +172,7 @@ def get_sql_results(self, query_id, return_results=True, store_results=False):
payload['query'] = query.to_dict()
payload = json.dumps(payload, default=utils.json_iso_dttm_ser)
if store_results and results_backend:
if store_results:
key = '{}'.format(uuid.uuid4())
logging.info("Storing results in results backend, key: {}".format(key))
results_backend.set(key, zlib.compress(payload))

View File

@ -2061,7 +2061,7 @@ class Superset(BaseSupersetView):
models.SqlaTable.table_name == table_name)
).first()
if not table:
json_error_response(__(
return json_error_response(__(
"Table %(t)s wasn't found in the database %(d)s",
t=table_name, s=db_name), status=404)
slices = session.query(models.Slice).filter_by(
@ -2378,6 +2378,9 @@ class Superset(BaseSupersetView):
@log_this
def results(self, key):
"""Serves a key off of the results backend"""
if not results_backend:
return json_error_response("Results backend isn't configured")
blob = results_backend.get(key)
if blob:
json_payload = zlib.decompress(blob)
@ -2387,7 +2390,7 @@ class Superset(BaseSupersetView):
mydb = session.query(models.Database).filter_by(id=db_id).one()
if not self.database_access(mydb):
json_error_response(
return json_error_response(
get_database_access_error_msg(mydb.database_name))
return Response(