chore(Network Errors): Update network errors on filter bars and charts (#31811)

Co-authored-by: Geido <60598000+geido@users.noreply.github.com>
This commit is contained in:
Mehmet Salih Yavuz 2025-01-28 21:13:43 +03:00 committed by GitHub
parent 6478bb7eab
commit 23d9f46d30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 90 additions and 6 deletions

View File

@ -35,6 +35,7 @@ type Props = {
descriptionDetails?: ReactNode;
errorMitigationFunction?: () => void;
fallback?: ReactNode;
compact?: boolean;
};
export default function ErrorMessageWithStackTrace({
@ -48,6 +49,7 @@ export default function ErrorMessageWithStackTrace({
description,
descriptionDetails,
fallback,
compact,
}: Props) {
// Check if a custom error message component was registered for this message
if (error) {
@ -57,6 +59,7 @@ export default function ErrorMessageWithStackTrace({
if (ErrorMessageComponent) {
return (
<ErrorMessageComponent
compact={compact}
error={error}
source={source}
subtitle={subtitle}
@ -89,6 +92,7 @@ export default function ErrorMessageWithStackTrace({
message={subtitle}
description={description}
descriptionDetails={computedDescriptionDetails}
compact={compact}
/>
);
}

View File

@ -0,0 +1,70 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ErrorLevel, ErrorSource, ErrorTypeEnum } from '@superset-ui/core';
import userEvent from '@testing-library/user-event';
import { render, screen } from 'spec/helpers/testing-library';
import FrontendNetworkErrorMessage from './FrontendNetworkErrorMessage';
jest.mock(
'src/components/Icons/Icon',
() =>
({ fileName }: { fileName: string }) => (
<span role="img" aria-label={fileName.replace('_', '-')} />
),
);
const mockedProps = {
error: {
error_type: ErrorTypeEnum.FRONTEND_NETWORK_ERROR,
extra: {},
level: 'error' as ErrorLevel,
message: 'Error message',
},
source: 'dashboard' as ErrorSource,
subtitle: 'Error message',
};
test('should render', () => {
const nullExtraProps = {
...mockedProps,
error: {
...mockedProps.error,
extra: null,
},
};
const { container } = render(
<FrontendNetworkErrorMessage {...nullExtraProps} />,
);
expect(container).toBeInTheDocument();
});
test('should render the error message', () => {
render(<FrontendNetworkErrorMessage {...mockedProps} />, { useRedux: true });
expect(screen.getByText('Error message')).toBeInTheDocument();
});
test("should render error message in compact mode if 'compact' is true", () => {
render(<FrontendNetworkErrorMessage {...mockedProps} compact />, {
useRedux: true,
});
expect(screen.queryByText('Error message')).not.toBeInTheDocument();
userEvent.click(screen.getByRole('button'));
expect(screen.getByText('Error message')).toBeInTheDocument();
});

View File

@ -24,10 +24,16 @@ import ErrorAlert from './ErrorAlert';
function FrontendNetworkErrorMessage({
error,
subtitle,
compact,
}: ErrorMessageComponentProps) {
const { level, message } = error;
return (
<ErrorAlert errorType={t('Network Error')} message={message} type={level} />
<ErrorAlert
compact={compact}
errorType={t('Network Error')}
message={message}
type={level}
/>
);
}
export default FrontendNetworkErrorMessage;

View File

@ -25,6 +25,7 @@ export type ErrorMessageComponentProps<ExtraType = Record<string, any> | null> =
error: SupersetError<ExtraType>;
source?: ErrorSource;
subtitle?: ReactNode;
compact?: boolean;
};
export type ErrorMessageComponent = ComponentType<ErrorMessageComponentProps>;

View File

@ -45,7 +45,6 @@ import { useDispatch, useSelector } from 'react-redux';
import { isEqual, isEqualWith } from 'lodash';
import { getChartDataRequest } from 'src/components/Chart/chartAction';
import Loading from 'src/components/Loading';
import BasicErrorAlert from 'src/components/ErrorMessage/BasicErrorAlert';
import ErrorMessageWithStackTrace from 'src/components/ErrorMessage/ErrorMessageWithStackTrace';
import { waitForAsyncData } from 'src/middleware/asyncEvent';
import { FilterBarOrientation, RootState } from 'src/dashboard/types';
@ -55,6 +54,7 @@ import {
} from 'src/dashboard/actions/dashboardState';
import { RESPONSIVE_WIDTH } from 'src/filters/components/common';
import { FAST_DEBOUNCE } from 'src/constants';
import ErrorAlert from 'src/components/ErrorMessage/ErrorAlert';
import { dispatchHoverAction, dispatchFocusAction } from './utils';
import { FilterControlProps } from './types';
import { getFormData } from '../../utils';
@ -106,6 +106,7 @@ const FilterValue: FC<FilterControlProps> = ({
const dashboardId = useSelector<RootState, number>(
state => state.dashboardInfo.id,
);
const [error, setError] = useState<ClientErrorObject>();
const [formData, setFormData] = useState<Partial<QueryFormData>>({
inView: false,
@ -305,11 +306,13 @@ const FilterValue: FC<FilterControlProps> = ({
return (
<ErrorMessageWithStackTrace
error={error.errors?.[0]}
compact
fallback={
<BasicErrorAlert
title={t('Cannot load filter')}
body={error.error}
level="error"
<ErrorAlert
errorType={t('Network error')}
message={t('Network error while attempting to fetch resource')}
type="error"
compact
/>
}
/>