mirror of https://github.com/apache/superset.git
feat: support new errors payload in SQL Lab (#10243)
This commit is contained in:
parent
2314aad450
commit
9a5195ab85
|
@ -19,12 +19,20 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import { Alert, ProgressBar } from 'react-bootstrap';
|
||||
|
||||
import FilterableTable from 'src/components/FilterableTable/FilterableTable';
|
||||
import ExploreResultsButton from 'src/SqlLab/components/ExploreResultsButton';
|
||||
import ResultSet from 'src/SqlLab/components/ResultSet';
|
||||
import { queries, stoppedQuery, runningQuery, cachedQuery } from './fixtures';
|
||||
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
|
||||
import {
|
||||
cachedQuery,
|
||||
failedQueryWithErrorMessage,
|
||||
failedQueryWithErrors,
|
||||
queries,
|
||||
runningQuery,
|
||||
stoppedQuery,
|
||||
} from './fixtures';
|
||||
|
||||
describe('ResultSet', () => {
|
||||
const clearQuerySpy = sinon.spy();
|
||||
|
@ -42,6 +50,14 @@ describe('ResultSet', () => {
|
|||
const stoppedQueryProps = { ...mockedProps, query: stoppedQuery };
|
||||
const runningQueryProps = { ...mockedProps, query: runningQuery };
|
||||
const cachedQueryProps = { ...mockedProps, query: cachedQuery };
|
||||
const failedQueryWithErrorMessageProps = {
|
||||
...mockedProps,
|
||||
query: failedQueryWithErrorMessage,
|
||||
};
|
||||
const failedQueryWithErrorsProps = {
|
||||
...mockedProps,
|
||||
query: failedQueryWithErrors,
|
||||
};
|
||||
const newProps = {
|
||||
query: {
|
||||
cached: false,
|
||||
|
@ -117,5 +133,15 @@ describe('ResultSet', () => {
|
|||
const wrapper = shallow(<ResultSet {...runningQueryProps} />);
|
||||
expect(wrapper.find(ProgressBar)).toHaveLength(1);
|
||||
});
|
||||
it('should render a failed query with an error message', () => {
|
||||
const wrapper = shallow(
|
||||
<ResultSet {...failedQueryWithErrorMessageProps} />,
|
||||
);
|
||||
expect(wrapper.find(ErrorMessageWithStackTrace)).toHaveLength(1);
|
||||
});
|
||||
it('should render a failed query with an errors object', () => {
|
||||
const wrapper = shallow(<ResultSet {...failedQueryWithErrorsProps} />);
|
||||
expect(wrapper.find(ErrorMessageWithStackTrace)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -389,6 +389,50 @@ export const stoppedQuery = {
|
|||
tab: 'Untitled Query 2',
|
||||
tempTable: '',
|
||||
};
|
||||
|
||||
export const failedQueryWithErrorMessage = {
|
||||
dbId: 1,
|
||||
cached: false,
|
||||
ctas: false,
|
||||
errorMessage: 'Something went wrong',
|
||||
id: 'ryhMUZCGb',
|
||||
progress: 0,
|
||||
results: [],
|
||||
runAsync: false,
|
||||
schema: 'main',
|
||||
sql: 'SELECT ...',
|
||||
sqlEditorId: 'rJaf5u9WZ',
|
||||
startDttm: 1497400851936,
|
||||
state: 'failed',
|
||||
tab: 'Untitled Query 2',
|
||||
tempTable: '',
|
||||
};
|
||||
|
||||
export const failedQueryWithErrors = {
|
||||
dbId: 1,
|
||||
cached: false,
|
||||
ctas: false,
|
||||
errors: [
|
||||
{
|
||||
message: 'Something went wrong',
|
||||
error_type: 'TEST_ERROR',
|
||||
level: 'error',
|
||||
extra: null,
|
||||
},
|
||||
],
|
||||
id: 'ryhMUZCGb',
|
||||
progress: 0,
|
||||
results: [],
|
||||
runAsync: false,
|
||||
schema: 'main',
|
||||
sql: 'SELECT ...',
|
||||
sqlEditorId: 'rJaf5u9WZ',
|
||||
startDttm: 1497400851936,
|
||||
state: 'failed',
|
||||
tab: 'Untitled Query 2',
|
||||
tempTable: '',
|
||||
};
|
||||
|
||||
export const runningQuery = {
|
||||
dbId: 1,
|
||||
cached: false,
|
||||
|
|
|
@ -271,7 +271,7 @@ export function querySuccess(query, results) {
|
|||
};
|
||||
}
|
||||
|
||||
export function queryFailed(query, msg, link) {
|
||||
export function queryFailed(query, msg, link, errors) {
|
||||
return function (dispatch) {
|
||||
const sync =
|
||||
!query.isDataPreview &&
|
||||
|
@ -283,7 +283,7 @@ export function queryFailed(query, msg, link) {
|
|||
: Promise.resolve();
|
||||
|
||||
return sync
|
||||
.then(() => dispatch({ type: QUERY_FAILED, query, msg, link }))
|
||||
.then(() => dispatch({ type: QUERY_FAILED, query, msg, link, errors }))
|
||||
.catch(() =>
|
||||
dispatch(
|
||||
addDangerToast(
|
||||
|
@ -332,7 +332,9 @@ export function fetchQueryResults(query, displayLimit) {
|
|||
error.statusText ||
|
||||
t('Failed at retrieving results');
|
||||
|
||||
return dispatch(queryFailed(query, message, error.link));
|
||||
return dispatch(
|
||||
queryFailed(query, message, error.link, error.errors),
|
||||
);
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
@ -376,7 +378,7 @@ export function runQuery(query) {
|
|||
if (message.includes('CSRF token')) {
|
||||
message = t(COMMON_ERR_MESSAGES.SESSION_TIMED_OUT);
|
||||
}
|
||||
dispatch(queryFailed(query, message, error.link));
|
||||
dispatch(queryFailed(query, message, error.link, error.errors));
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@ import { Alert, Button, ButtonGroup, ProgressBar } from 'react-bootstrap';
|
|||
import shortid from 'shortid';
|
||||
import { t } from '@superset-ui/translation';
|
||||
|
||||
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
|
||||
import Loading from '../../components/Loading';
|
||||
import ExploreCtasResultsButton from './ExploreCtasResultsButton';
|
||||
import ExploreResultsButton from './ExploreResultsButton';
|
||||
|
@ -215,15 +216,11 @@ export default class ResultSet extends React.PureComponent<
|
|||
return <Alert bsStyle="warning">Query was stopped</Alert>;
|
||||
} else if (query.state === 'failed') {
|
||||
return (
|
||||
<Alert bsStyle="danger">
|
||||
{query.errorMessage}
|
||||
{query.link && (
|
||||
<a href={query.link} target="_blank" rel="noopener noreferrer">
|
||||
{' '}
|
||||
{t('(Request Access)')}{' '}
|
||||
</a>
|
||||
)}
|
||||
</Alert>
|
||||
<ErrorMessageWithStackTrace
|
||||
error={query.errors?.[0]}
|
||||
message={query.errorMessage || undefined}
|
||||
link={query.link}
|
||||
/>
|
||||
);
|
||||
} else if (query.state === 'success' && query.ctas) {
|
||||
const { tempSchema, tempTable } = query;
|
||||
|
|
|
@ -343,6 +343,7 @@ export default function sqlLabReducer(state = {}, action) {
|
|||
}
|
||||
const alts = {
|
||||
state: 'failed',
|
||||
errors: action.errors,
|
||||
errorMessage: action.msg,
|
||||
endDttm: now(),
|
||||
link: action.link,
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { CtasEnum } from './actions/sqlLab';
|
||||
import { SupersetError } from 'src/components/ErrorMessage/types';
|
||||
import { CtasEnum } from 'src/SqlLab/actions/sqlLab';
|
||||
|
||||
export type Column = {
|
||||
name: string;
|
||||
|
@ -27,6 +28,7 @@ export type Query = {
|
|||
ctas: boolean;
|
||||
ctas_method?: keyof typeof CtasEnum;
|
||||
dbId: number;
|
||||
errors?: SupersetError[];
|
||||
errorMessage: string | null;
|
||||
extra: {
|
||||
progress: string | null;
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
import React, { useState } from 'react';
|
||||
// @ts-ignore
|
||||
import { Alert, Collapse } from 'react-bootstrap';
|
||||
import { t } from '@superset-ui/translation';
|
||||
|
||||
import getErrorMessageComponentRegistry from './getErrorMessageComponentRegistry';
|
||||
import { SupersetError } from './types';
|
||||
|
||||
type Props = {
|
||||
error?: SupersetError;
|
||||
link?: string;
|
||||
message: string;
|
||||
message?: string;
|
||||
stackTrace?: string;
|
||||
};
|
||||
|
||||
|
@ -54,7 +56,7 @@ export default function ErrorMessageWithStackTrace({
|
|||
bsStyle="warning"
|
||||
onClick={() => setShowStackTrace(!showStackTrace)}
|
||||
>
|
||||
{message}
|
||||
{message || t('An error occurred.')}
|
||||
{link && (
|
||||
<a href={link} target="_blank" rel="noopener noreferrer">
|
||||
(Request Access)
|
||||
|
|
Loading…
Reference in New Issue