diff --git a/superset-frontend/src/components/ErrorMessage/BasicErrorAlert.tsx b/superset-frontend/src/components/ErrorMessage/BasicErrorAlert.tsx
index fdc61b8891..918aee5f24 100644
--- a/superset-frontend/src/components/ErrorMessage/BasicErrorAlert.tsx
+++ b/superset-frontend/src/components/ErrorMessage/BasicErrorAlert.tsx
@@ -37,6 +37,7 @@ const StyledContent = styled.div`
display: flex;
flex-direction: column;
margin-left: ${({ theme }) => theme.gridUnit * 2}px;
+ overflow: hidden;
`;
const StyledTitle = styled.span`
diff --git a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.test.tsx b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.test.tsx
index ae30e5cb99..99f22955a3 100644
--- a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.test.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.test.tsx
@@ -21,7 +21,8 @@ import React from 'react';
import { render, screen } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import ErrorMessageWithStackTrace from './ErrorMessageWithStackTrace';
-import { ErrorLevel, ErrorSource } from './types';
+import BasicErrorAlert from './BasicErrorAlert';
+import { ErrorLevel, ErrorSource, ErrorTypeEnum } from './types';
jest.mock(
'src/components/Icons/Icon',
@@ -57,3 +58,21 @@ test('should render the link', () => {
expect(link).toHaveTextContent('(Request Access)');
expect(link).toHaveAttribute('href', mockedProps.link);
});
+
+test('should render the fallback', () => {
+ const body = 'Blahblah';
+ render(
+ }
+ {...mockedProps}
+ />,
+ { useRedux: true },
+ );
+ expect(screen.getByText(body)).toBeInTheDocument();
+});
diff --git a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
index b54277b4ac..b9e7e5c053 100644
--- a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
@@ -34,6 +34,7 @@ type Props = {
source?: ErrorSource;
description?: string;
errorMitigationFunction?: () => void;
+ fallback?: React.ReactNode;
};
export default function ErrorMessageWithStackTrace({
@@ -45,6 +46,7 @@ export default function ErrorMessageWithStackTrace({
stackTrace,
source,
description,
+ fallback,
}: Props) {
// Check if a custom error message component was registered for this message
if (error) {
@@ -62,6 +64,10 @@ export default function ErrorMessageWithStackTrace({
}
}
+ if (fallback) {
+ return <>{fallback}>;
+ }
+
return (
= ({
const dependencies = useFilterDependencies(id, dataMaskSelected);
const shouldRefresh = useShouldFilterRefresh();
const [state, setState] = useState([]);
- const [error, setError] = useState('');
+ const [error, setError] = useState();
const [formData, setFormData] = useState>({
inView: false,
});
@@ -183,11 +187,11 @@ const FilterValue: React.FC = ({
setState(asyncResult);
handleFilterLoadFinish();
})
- .catch((error: ClientErrorObject) => {
- setError(
- error.message || error.error || t('Check configuration'),
- );
- handleFilterLoadFinish();
+ .catch((error: Response) => {
+ getClientErrorObject(error).then(clientErrorObject => {
+ setError(clientErrorObject);
+ handleFilterLoadFinish();
+ });
});
} else {
throw new Error(
@@ -196,13 +200,15 @@ const FilterValue: React.FC = ({
}
} else {
setState(json.result);
- setError('');
+ setError(undefined);
handleFilterLoadFinish();
}
})
.catch((error: Response) => {
- setError(error.statusText);
- handleFilterLoadFinish();
+ getClientErrorObject(error).then(clientErrorObject => {
+ setError(clientErrorObject);
+ handleFilterLoadFinish();
+ });
});
}
}, [
@@ -298,10 +304,15 @@ const FilterValue: React.FC = ({
if (error) {
return (
-
+ }
/>
);
}
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
index d617e51e48..240c9e41b8 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FiltersConfigForm.tsx
@@ -54,6 +54,7 @@ import { Input, TextArea } from 'src/components/Input';
import { Select, FormInstance } from 'src/components';
import Collapse from 'src/components/Collapse';
import BasicErrorAlert from 'src/components/ErrorMessage/BasicErrorAlert';
+import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
import { FormItem } from 'src/components/Form';
import Icons from 'src/components/Icons';
import Loading from 'src/components/Loading';
@@ -72,7 +73,10 @@ import DateFilterControl from 'src/explore/components/controls/DateFilterControl
import AdhocFilterControl from 'src/explore/components/controls/FilterControl/AdhocFilterControl';
import { isFeatureEnabled } from 'src/featureFlags';
import { waitForAsyncData } from 'src/middleware/asyncEvent';
-import { ClientErrorObject } from 'src/utils/getClientErrorObject';
+import {
+ ClientErrorObject,
+ getClientErrorObject,
+} from 'src/utils/getClientErrorObject';
import { SingleValueType } from 'src/filters/components/Range/SingleValueType';
import {
getFormData,
@@ -345,7 +349,7 @@ const FiltersConfigForm = (
ref: React.RefObject,
) => {
const isRemoved = !!removedFilters[filterId];
- const [error, setError] = useState('');
+ const [error, setError] = useState();
const [metrics, setMetrics] = useState([]);
const [activeTabKey, setActiveTabKey] = useState(
FilterTabs.configuration.key,
@@ -440,11 +444,11 @@ const FiltersConfigForm = (
const setNativeFilterFieldValuesWrapper = (values: object) => {
setNativeFilterFieldValues(form, filterId, values);
- setError('');
+ setError(undefined);
forceUpdate();
};
- const setErrorWrapper = (error: string) => {
+ const setErrorWrapper = (error: ClientErrorObject) => {
setNativeFilterFieldValues(form, filterId, {
defaultValueQueriesData: null,
});
@@ -506,10 +510,10 @@ const FiltersConfigForm = (
defaultValueQueriesData: asyncResult,
});
})
- .catch((error: ClientErrorObject) => {
- setError(
- error.message || error.error || t('Check configuration'),
- );
+ .catch((error: Response) => {
+ getClientErrorObject(error).then(clientErrorObject => {
+ setErrorWrapper(clientErrorObject);
+ });
});
} else {
throw new Error(
@@ -523,10 +527,8 @@ const FiltersConfigForm = (
}
})
.catch((error: Response) => {
- error.json().then(body => {
- setErrorWrapper(
- body.message || error.statusText || t('Check configuration'),
- );
+ getClientErrorObject(error).then(clientErrorObject => {
+ setError(clientErrorObject);
});
});
},
@@ -1224,10 +1226,15 @@ const FiltersConfigForm = (
{error || showDefaultValue ? (
{error ? (
-
+ }
/>
) : (