mirror of
https://github.com/apache/superset.git
synced 2026-05-03 06:54:19 +00:00
Compare commits
2 Commits
fix/check-
...
chore/cons
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4374e7e9d7 | ||
|
|
92d4e16de6 |
13
superset-frontend/package-lock.json
generated
13
superset-frontend/package-lock.json
generated
@@ -50000,12 +50000,15 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-error-boundary": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.0.tgz",
|
||||
"integrity": "sha512-02k9WQ/mUhdbXir0tC1NiMesGzRPaCsJEWU/4bcFrbY1YMZOtHShtZP6zw0SJrBWA/31H0KT9/FgdL8+sPKgHA==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.0.0.tgz",
|
||||
"integrity": "sha512-gdlJjD7NWr0IfkPlaREN2d9uUZUlksrfOx7SX62VRerwXbMY6ftGCIZua1VG1aXFNOimhISsTq+Owp725b9SiA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0 || ^19.0.0"
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-google-recaptcha": {
|
||||
@@ -63712,7 +63715,7 @@
|
||||
"re-resizable": "^6.11.2",
|
||||
"react-ace": "^14.0.1",
|
||||
"react-draggable": "^4.5.0",
|
||||
"react-error-boundary": "^6.1.0",
|
||||
"react-error-boundary": "6.0.0",
|
||||
"react-js-cron": "^5.2.0",
|
||||
"react-markdown": "^8.0.7",
|
||||
"react-resize-detector": "^7.1.2",
|
||||
|
||||
@@ -52,10 +52,10 @@
|
||||
"react-ace": "^14.0.1",
|
||||
"react-js-cron": "^5.2.0",
|
||||
"react-draggable": "^4.5.0",
|
||||
"react-error-boundary": "6.0.0",
|
||||
"react-resize-detector": "^7.1.2",
|
||||
"react-syntax-highlighter": "^16.1.0",
|
||||
"react-ultimate-pagination": "^1.3.2",
|
||||
"react-error-boundary": "^6.1.0",
|
||||
"react-markdown": "^8.0.7",
|
||||
"regenerator-runtime": "^0.14.1",
|
||||
"rehype-raw": "^7.0.0",
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 { ReactNode, ComponentType, ErrorInfo } from 'react';
|
||||
import {
|
||||
ErrorBoundary as ReactErrorBoundary,
|
||||
FallbackProps,
|
||||
useErrorBoundary,
|
||||
withErrorBoundary,
|
||||
} from 'react-error-boundary';
|
||||
|
||||
/**
|
||||
* Props for ErrorBoundary component.
|
||||
* All fallback props are optional - defaults to rendering null on error.
|
||||
*/
|
||||
export interface ErrorBoundaryProps {
|
||||
children: ReactNode;
|
||||
FallbackComponent?: ComponentType<FallbackProps>;
|
||||
fallbackRender?: (props: FallbackProps) => ReactNode;
|
||||
fallback?: ReactNode;
|
||||
onError?: (error: Error, info: ErrorInfo) => void;
|
||||
onReset?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default fallback that renders nothing (preserves original Superset behavior).
|
||||
*/
|
||||
const defaultFallback = () => null;
|
||||
|
||||
/**
|
||||
* ErrorBoundary wrapper that makes fallback optional.
|
||||
* Uses react-error-boundary under the hood but allows usage without
|
||||
* specifying a fallback (defaults to null, matching original behavior).
|
||||
*/
|
||||
export function ErrorBoundary({
|
||||
children,
|
||||
FallbackComponent,
|
||||
fallbackRender,
|
||||
fallback,
|
||||
onError,
|
||||
onReset,
|
||||
}: ErrorBoundaryProps) {
|
||||
if (FallbackComponent) {
|
||||
return (
|
||||
<ReactErrorBoundary
|
||||
FallbackComponent={FallbackComponent}
|
||||
onError={onError}
|
||||
onReset={onReset}
|
||||
>
|
||||
{children}
|
||||
</ReactErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
if (fallbackRender) {
|
||||
return (
|
||||
<ReactErrorBoundary
|
||||
fallbackRender={fallbackRender}
|
||||
onError={onError}
|
||||
onReset={onReset}
|
||||
>
|
||||
{children}
|
||||
</ReactErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
if (fallback !== undefined) {
|
||||
return (
|
||||
<ReactErrorBoundary
|
||||
fallback={fallback}
|
||||
onError={onError}
|
||||
onReset={onReset}
|
||||
>
|
||||
{children}
|
||||
</ReactErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
// Default: render null on error
|
||||
return (
|
||||
<ReactErrorBoundary
|
||||
fallbackRender={defaultFallback}
|
||||
onError={onError}
|
||||
onReset={onReset}
|
||||
>
|
||||
{children}
|
||||
</ReactErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
export { type FallbackProps, useErrorBoundary, withErrorBoundary };
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
ErrorBoundary,
|
||||
ErrorBoundaryProps,
|
||||
FallbackProps,
|
||||
} from 'react-error-boundary';
|
||||
} from './ErrorBoundary';
|
||||
import { ParentSize } from '@visx/responsive';
|
||||
import { createSelector } from 'reselect';
|
||||
import { withTheme } from '@emotion/react';
|
||||
|
||||
@@ -26,6 +26,13 @@ export { ChartProps };
|
||||
export type { ChartPropsConfig };
|
||||
|
||||
export { default as createLoadableRenderer } from './components/createLoadableRenderer';
|
||||
export {
|
||||
ErrorBoundary,
|
||||
type ErrorBoundaryProps,
|
||||
type FallbackProps,
|
||||
useErrorBoundary,
|
||||
withErrorBoundary,
|
||||
} from './components/ErrorBoundary';
|
||||
export { default as reactify } from './components/reactify';
|
||||
export { default as SuperChart } from './components/SuperChart';
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import '@testing-library/jest-dom';
|
||||
import { render, screen } from '@superset-ui/core/spec';
|
||||
import mockConsole, { RestoreConsole } from 'jest-mock-console';
|
||||
import { triggerResizeObserver } from 'resize-observer-polyfill';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { ErrorBoundary } from '../../../src/chart/components/ErrorBoundary';
|
||||
|
||||
import { promiseTimeout, SuperChart } from '@superset-ui/core';
|
||||
import { WrapperProps } from '../../../src/chart/components/SuperChart';
|
||||
|
||||
@@ -33,7 +33,7 @@ import { styled } from '@apache-superset/core/ui';
|
||||
import type { ChartState, Datasource, ChartStatus } from 'src/explore/types';
|
||||
import { PLACEHOLDER_DATASOURCE } from 'src/dashboard/constants';
|
||||
import { EmptyState, Loading } from '@superset-ui/core/components';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { Logger, LOG_ACTIONS_RENDER_CHART } from 'src/logger/LogUtils';
|
||||
import { URL_PARAMS } from 'src/constants';
|
||||
import { getUrlParam } from 'src/utils/urlUtils';
|
||||
@@ -396,10 +396,7 @@ class Chart extends PureComponent<ChartProps, {}> {
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorBoundary
|
||||
onError={this.handleRenderContainerFailure}
|
||||
showMessage={false}
|
||||
>
|
||||
<ErrorBoundary onError={this.handleRenderContainerFailure}>
|
||||
<Styles
|
||||
data-ui-anchor="chart"
|
||||
className="chart-container"
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* 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 { ReactElement } from 'react';
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import type { ErrorBoundaryProps } from './types';
|
||||
import { ErrorBoundary } from '.';
|
||||
|
||||
const mockedProps: Partial<ErrorBoundaryProps> = {
|
||||
children: <span>Error children</span>,
|
||||
onError: jest.fn(),
|
||||
showMessage: false,
|
||||
};
|
||||
|
||||
const Child = (): ReactElement => {
|
||||
throw new Error('Thrown error');
|
||||
};
|
||||
|
||||
test('should render', () => {
|
||||
const { container } = render(
|
||||
<ErrorBoundary {...mockedProps}>
|
||||
<Child />
|
||||
</ErrorBoundary>,
|
||||
);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should not render an error message', () => {
|
||||
render(
|
||||
<ErrorBoundary {...mockedProps}>
|
||||
<Child />
|
||||
</ErrorBoundary>,
|
||||
);
|
||||
expect(screen.queryByText('Unexpected error')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render an error message', () => {
|
||||
const messageProps = {
|
||||
...mockedProps,
|
||||
showMessage: true,
|
||||
};
|
||||
render(
|
||||
<ErrorBoundary {...messageProps}>
|
||||
<Child />
|
||||
</ErrorBoundary>,
|
||||
);
|
||||
expect(screen.getByText('Unexpected error')).toBeInTheDocument();
|
||||
});
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* 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 { Component, ErrorInfo } from 'react';
|
||||
import { t } from '@apache-superset/core';
|
||||
import { ErrorAlert } from '../ErrorMessage';
|
||||
import type { ErrorBoundaryProps, ErrorBoundaryState } from './types';
|
||||
|
||||
export class ErrorBoundary extends Component<
|
||||
ErrorBoundaryProps,
|
||||
ErrorBoundaryState
|
||||
> {
|
||||
static defaultProps: Partial<ErrorBoundaryProps> = {
|
||||
showMessage: true,
|
||||
};
|
||||
|
||||
constructor(props: ErrorBoundaryProps) {
|
||||
super(props);
|
||||
this.state = { error: null, info: null };
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: ErrorInfo): void {
|
||||
this.props.onError?.(error, info);
|
||||
this.setState({ error, info });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { error, info } = this.state;
|
||||
const { showMessage, className } = this.props;
|
||||
if (error) {
|
||||
const firstLine = error.toString().split('\n')[0];
|
||||
if (showMessage) {
|
||||
return (
|
||||
<ErrorAlert
|
||||
errorType={t('Unexpected error')}
|
||||
message={firstLine}
|
||||
descriptionDetails={info?.componentStack}
|
||||
className={className}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
export type { ErrorBoundaryProps };
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* 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 type { ErrorInfo, ReactNode } from 'react';
|
||||
|
||||
export interface ErrorBoundaryProps {
|
||||
children: ReactNode;
|
||||
onError?: (error: Error, info: ErrorInfo) => void;
|
||||
showMessage?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface ErrorBoundaryState {
|
||||
error: Error | null;
|
||||
info: ErrorInfo | null;
|
||||
}
|
||||
@@ -36,7 +36,6 @@ export { DatabaseSelector, type DatabaseObject } from './DatabaseSelector';
|
||||
export * from './Datasource';
|
||||
export * from './ErrorMessage';
|
||||
export { ImportModal, type ImportModelsModalProps } from './ImportModal';
|
||||
export { ErrorBoundary, type ErrorBoundaryProps } from './ErrorBoundary';
|
||||
export * from './GenericLink';
|
||||
export { GridTable, type TableProps } from './GridTable';
|
||||
export * from './Tag';
|
||||
|
||||
@@ -24,7 +24,8 @@ import { addAlpha, JsonObject, useElementOnScreen } from '@superset-ui/core';
|
||||
import { css, styled, useTheme } from '@apache-superset/core/ui';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { EmptyState, Loading } from '@superset-ui/core/components';
|
||||
import { ErrorBoundary, BasicErrorAlert } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { BasicErrorAlert } from 'src/components';
|
||||
import BuilderComponentPane from 'src/dashboard/components/BuilderComponentPane';
|
||||
import DashboardHeader from 'src/dashboard/components/Header';
|
||||
import { Icons } from '@superset-ui/core/components/Icons';
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
import { ReactNode, useState, useCallback } from 'react';
|
||||
import type { FormInstance } from '@superset-ui/core/components';
|
||||
import { ErrorBoundary } from 'src/components/ErrorBoundary';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { BaseModalBody, BaseForm, BaseModalWrapper } from './SharedStyles';
|
||||
import { ModalFooter } from './ModalFooter';
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { t } from '@apache-superset/core';
|
||||
import { ChartCustomizationType, NativeFilterType } from '@superset-ui/core';
|
||||
import { styled, css, useTheme } from '@apache-superset/core/ui';
|
||||
import { Constants, Form, Icons, Flex } from '@superset-ui/core/components';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { testWithId } from 'src/utils/testUtils';
|
||||
import useEffectEvent from 'src/hooks/useEffectEvent';
|
||||
import {
|
||||
|
||||
@@ -32,7 +32,7 @@ import setupPlugins from 'src/setup/setupPlugins';
|
||||
import { useUiConfig } from 'src/components/UiConfigContext';
|
||||
import { store, USER_LOADED } from 'src/views/store';
|
||||
import { Loading } from '@superset-ui/core/components';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { addDangerToast } from 'src/components/MessageToasts/actions';
|
||||
import ToastContainer from 'src/components/MessageToasts/ToastContainer';
|
||||
import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes';
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { JsonValue, QueryFormData, usePrevious } from '@superset-ui/core';
|
||||
import { styled } from '@apache-superset/core/ui';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { ExploreActions } from 'src/explore/actions/exploreActions';
|
||||
import controlMap from './controls';
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import type React from 'react';
|
||||
import { createRef, Component, type RefObject } from 'react';
|
||||
import type { SupersetTheme } from '@apache-superset/core/ui';
|
||||
import { Button, Icons, Select } from '@superset-ui/core/components';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { SupersetClient } from '@superset-ui/core';
|
||||
import { t } from '@apache-superset/core';
|
||||
import { styled } from '@apache-superset/core/ui';
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
useEffect,
|
||||
useMemo,
|
||||
} from 'react';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { setExtensionsContextValue } from './ExtensionsContextUtils';
|
||||
import ExtensionPlaceholder from './ExtensionPlaceholder';
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ import ChartCard from 'src/features/charts/ChartCard';
|
||||
import Chart from 'src/types/Chart';
|
||||
import handleResourceExport from 'src/utils/export';
|
||||
import { Loading } from '@superset-ui/core/components';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import { Icons } from '@superset-ui/core/components/Icons';
|
||||
import { navigateTo } from 'src/utils/navigationUtils';
|
||||
import EmptyState from './EmptyState';
|
||||
|
||||
@@ -27,7 +27,7 @@ import { bindActionCreators } from 'redux';
|
||||
import { css } from '@apache-superset/core/ui';
|
||||
import { Layout, Loading } from '@superset-ui/core/components';
|
||||
import { setupAGGridModules } from '@superset-ui/core/components/ThemedAgGridReact';
|
||||
import { ErrorBoundary } from 'src/components';
|
||||
import { ErrorBoundary } from '@superset-ui/core';
|
||||
import Menu from 'src/features/home/Menu';
|
||||
import getBootstrapData, { applicationRoot } from 'src/utils/getBootstrapData';
|
||||
import ToastContainer from 'src/components/MessageToasts/ToastContainer';
|
||||
@@ -91,11 +91,7 @@ const App = () => (
|
||||
flex-direction: column;
|
||||
`}
|
||||
>
|
||||
<ErrorBoundary
|
||||
css={css`
|
||||
margin: 16px;
|
||||
`}
|
||||
>
|
||||
<ErrorBoundary>
|
||||
<Component user={bootstrapData.user} {...props} />
|
||||
</ErrorBoundary>
|
||||
</Layout.Content>
|
||||
|
||||
Reference in New Issue
Block a user