This is an automated email from the ASF dual-hosted git repository.

erikrit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a5195a  feat: support new errors payload in SQL Lab (#10243)
9a5195a is described below

commit 9a5195ab8513f2f5da5133d827f3a71c2cccb30e
Author: Erik Ritter <erik.rit...@airbnb.com>
AuthorDate: Mon Jul 6 09:49:32 2020 -0700

    feat: support new errors payload in SQL Lab (#10243)
---
 .../spec/javascripts/sqllab/ResultSet_spec.jsx     | 30 ++++++++++++++-
 .../spec/javascripts/sqllab/fixtures.js            | 44 ++++++++++++++++++++++
 superset-frontend/src/SqlLab/actions/sqlLab.js     | 10 +++--
 .../src/SqlLab/components/ResultSet.tsx            | 15 +++-----
 superset-frontend/src/SqlLab/reducers/sqlLab.js    |  1 +
 superset-frontend/src/SqlLab/types.ts              |  4 +-
 .../ErrorMessage/ErrorMessageWithStackTrace.tsx    |  6 ++-
 7 files changed, 92 insertions(+), 18 deletions(-)

diff --git a/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx 
b/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx
index e77b1c8..dcba856 100644
--- a/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx
+++ b/superset-frontend/spec/javascripts/sqllab/ResultSet_spec.jsx
@@ -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);
+    });
   });
 });
diff --git a/superset-frontend/spec/javascripts/sqllab/fixtures.js 
b/superset-frontend/spec/javascripts/sqllab/fixtures.js
index 45bbb2e..e7503ee 100644
--- a/superset-frontend/spec/javascripts/sqllab/fixtures.js
+++ b/superset-frontend/spec/javascripts/sqllab/fixtures.js
@@ -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,
diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.js 
b/superset-frontend/src/SqlLab/actions/sqlLab.js
index e38a4fe..8fb7428 100644
--- a/superset-frontend/src/SqlLab/actions/sqlLab.js
+++ b/superset-frontend/src/SqlLab/actions/sqlLab.js
@@ -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));
         }),
       );
   };
diff --git a/superset-frontend/src/SqlLab/components/ResultSet.tsx 
b/superset-frontend/src/SqlLab/components/ResultSet.tsx
index 75273b3..b074872 100644
--- a/superset-frontend/src/SqlLab/components/ResultSet.tsx
+++ b/superset-frontend/src/SqlLab/components/ResultSet.tsx
@@ -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;
diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.js 
b/superset-frontend/src/SqlLab/reducers/sqlLab.js
index 6257ce8..d47a45a 100644
--- a/superset-frontend/src/SqlLab/reducers/sqlLab.js
+++ b/superset-frontend/src/SqlLab/reducers/sqlLab.js
@@ -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,
diff --git a/superset-frontend/src/SqlLab/types.ts 
b/superset-frontend/src/SqlLab/types.ts
index 3b1c4e1..0fe83a7 100644
--- a/superset-frontend/src/SqlLab/types.ts
+++ b/superset-frontend/src/SqlLab/types.ts
@@ -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;
diff --git 
a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx 
b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
index fff4e06..5f3f679 100644
--- 
a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
+++ 
b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
@@ -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)

Reply via email to