feat: refactor to error display instead
Signed-off-by: benjdlambert <ben@blam.sh>
This commit is contained in:
@@ -27,7 +27,7 @@ import {
|
||||
iconsApiRef,
|
||||
useApi,
|
||||
routeResolutionApiRef,
|
||||
ErrorBoundary,
|
||||
ErrorDisplay,
|
||||
NotFoundErrorPage,
|
||||
Progress,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
@@ -102,7 +102,7 @@ function LegacyAppContextProvider(props: { children: ReactNode }) {
|
||||
|
||||
const ErrorBoundaryFallbackWrapper: AppComponents['ErrorBoundaryFallback'] =
|
||||
({ plugin, ...rest }) => (
|
||||
<ErrorBoundary {...rest} plugin={plugin && toNewPlugin(plugin)} />
|
||||
<ErrorDisplay {...rest} plugin={plugin && toNewPlugin(plugin)} />
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
AnyRouteRefParams,
|
||||
SwappableComponentRef,
|
||||
SwappableComponentsApi,
|
||||
CoreErrorBoundaryFallbackProps,
|
||||
CoreErrorDisplayProps,
|
||||
CoreNotFoundErrorPageProps,
|
||||
CoreProgressProps,
|
||||
ExternalRouteRef,
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
routeResolutionApiRef,
|
||||
Progress,
|
||||
NotFoundErrorPage,
|
||||
ErrorBoundary,
|
||||
ErrorDisplay,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { ComponentType, useMemo } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
@@ -54,11 +54,11 @@ import { convertLegacyRouteRef } from '../convertLegacyRouteRef';
|
||||
class CompatComponentsApi implements SwappableComponentsApi {
|
||||
readonly #Progress: ComponentType<CoreProgressProps>;
|
||||
readonly #NotFoundErrorPage: ComponentType<CoreNotFoundErrorPageProps>;
|
||||
readonly #ErrorBoundaryFallback: ComponentType<CoreErrorBoundaryFallbackProps>;
|
||||
readonly #ErrorBoundaryFallback: ComponentType<CoreErrorDisplayProps>;
|
||||
|
||||
constructor(app: AppContext) {
|
||||
const components = app.getComponents();
|
||||
const ErrorBoundaryFallback = (props: CoreErrorBoundaryFallbackProps) => (
|
||||
const ErrorBoundaryFallback = (props: CoreErrorDisplayProps) => (
|
||||
<components.ErrorBoundaryFallback
|
||||
{...props}
|
||||
plugin={props.plugin && toLegacyPlugin(props.plugin)}
|
||||
@@ -87,7 +87,7 @@ class CompatComponentsApi implements SwappableComponentsApi {
|
||||
return (() => this.#NotFoundErrorPage) as () => (
|
||||
props: object,
|
||||
) => JSX.Element | null;
|
||||
case ErrorBoundary.ref.id:
|
||||
case ErrorDisplay.ref.id:
|
||||
return (() => this.#ErrorBoundaryFallback) as () => (
|
||||
props: object,
|
||||
) => JSX.Element | null;
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
createRouteRef as createNewRouteRef,
|
||||
useApi,
|
||||
NotFoundErrorPage,
|
||||
ErrorBoundary,
|
||||
ErrorDisplay,
|
||||
Progress,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import {
|
||||
@@ -102,7 +102,7 @@ describe('ForwardsCompatProvider', () => {
|
||||
const defaultComponentRefs = {
|
||||
progress: Progress.ref,
|
||||
notFoundErrorPage: NotFoundErrorPage.ref,
|
||||
errorBoundary: ErrorBoundary.ref,
|
||||
errorDisplay: ErrorDisplay.ref,
|
||||
};
|
||||
|
||||
function Component() {
|
||||
@@ -126,7 +126,7 @@ describe('ForwardsCompatProvider', () => {
|
||||
await renderInOldTestApp(compatWrapper(<Component />));
|
||||
|
||||
expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(`
|
||||
"components: progress=true, notFoundErrorPage=true, errorBoundary=true
|
||||
"components: progress=true, notFoundErrorPage=true, errorDisplay=true
|
||||
icons: kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, user, warning, star, unstarred"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ComponentType } from 'react';
|
||||
import {
|
||||
SwappableComponentBlueprint,
|
||||
ApiBlueprint,
|
||||
CoreErrorBoundaryFallbackProps,
|
||||
CoreErrorDisplayProps,
|
||||
createExtension,
|
||||
createFrontendModule,
|
||||
ExtensionDefinition,
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
RouterBlueprint,
|
||||
SignInPageBlueprint,
|
||||
ThemeBlueprint,
|
||||
ErrorBoundary as SwappableErrorBoundary,
|
||||
ErrorDisplay as SwappableErrorDisplay,
|
||||
NotFoundErrorPage as SwappableNotFoundErrorPage,
|
||||
Progress as SwappableProgress,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
@@ -179,9 +179,7 @@ export function convertLegacyAppOptions(
|
||||
}
|
||||
|
||||
if (ErrorBoundaryFallback) {
|
||||
const WrappedErrorBoundaryFallback = (
|
||||
props: CoreErrorBoundaryFallbackProps,
|
||||
) =>
|
||||
const WrappedErrorBoundaryFallback = (props: CoreErrorDisplayProps) =>
|
||||
compatWrapper(
|
||||
<ErrorBoundaryFallback
|
||||
{...props}
|
||||
@@ -193,7 +191,7 @@ export function convertLegacyAppOptions(
|
||||
SwappableComponentBlueprint.make({
|
||||
params: define =>
|
||||
define({
|
||||
component: SwappableErrorBoundary,
|
||||
component: SwappableErrorDisplay,
|
||||
loader: () =>
|
||||
componentCompatWrapper(WrappedErrorBoundaryFallback),
|
||||
}),
|
||||
|
||||
@@ -40,5 +40,5 @@ export interface SwappableComponentsApi {
|
||||
* @public
|
||||
*/
|
||||
export const swappableComponentsApiRef = createApiRef<SwappableComponentsApi>({
|
||||
id: 'core.swappableComponents',
|
||||
id: 'core.swappable-components',
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
CoreErrorBoundaryFallbackProps,
|
||||
CoreErrorDisplayProps,
|
||||
CoreNotFoundErrorPageProps,
|
||||
CoreProgressProps,
|
||||
} from '../types';
|
||||
@@ -39,7 +39,6 @@ export const NotFoundErrorPage =
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const ErrorBoundary =
|
||||
createSwappableComponent<CoreErrorBoundaryFallbackProps>({
|
||||
id: 'core.components.errorBoundary',
|
||||
});
|
||||
export const ErrorDisplay = createSwappableComponent<CoreErrorDisplayProps>({
|
||||
id: 'core.components.errorDisplay',
|
||||
});
|
||||
|
||||
@@ -14,13 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, ComponentType, PropsWithChildren } from 'react';
|
||||
import { Component, PropsWithChildren } from 'react';
|
||||
import { FrontendPlugin } from '../wiring';
|
||||
import { CoreErrorBoundaryFallbackProps } from '../types';
|
||||
import { ErrorDisplay } from './DefaultSwappableComponents';
|
||||
|
||||
type ErrorBoundaryProps = PropsWithChildren<{
|
||||
plugin?: FrontendPlugin;
|
||||
Fallback: ComponentType<CoreErrorBoundaryFallbackProps>;
|
||||
}>;
|
||||
type ErrorBoundaryState = { error?: Error };
|
||||
|
||||
@@ -41,13 +40,15 @@ export class ErrorBoundary extends Component<
|
||||
|
||||
render() {
|
||||
const { error } = this.state;
|
||||
const { plugin, children, Fallback } = this.props;
|
||||
const { plugin, children } = this.props;
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<Fallback
|
||||
<ErrorDisplay
|
||||
// todo: do we want to just use useAppNode hook in the ErrorDisplay instead?
|
||||
plugin={plugin}
|
||||
error={error}
|
||||
// todo: probably change this to onResetError
|
||||
resetError={this.handleErrorReset}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -29,7 +29,6 @@ import { AppNode } from '../apis';
|
||||
import { Progress } from '@backstage/core-components';
|
||||
import { coreExtensionData } from '../wiring';
|
||||
import { AppNodeProvider } from './AppNodeProvider';
|
||||
import { ErrorBoundary as ErrorBoundaryComponent } from './DefaultSwappableComponents';
|
||||
|
||||
type RouteTrackerProps = PropsWithChildren<{
|
||||
enabled?: boolean;
|
||||
@@ -77,7 +76,7 @@ export function ExtensionBoundary(props: ExtensionBoundaryProps) {
|
||||
return (
|
||||
<AppNodeProvider node={node}>
|
||||
<Suspense fallback={<Progress />}>
|
||||
<ErrorBoundary plugin={plugin} Fallback={ErrorBoundaryComponent}>
|
||||
<ErrorBoundary plugin={plugin}>
|
||||
<AnalyticsContext attributes={attributes}>
|
||||
<RouteTracker enabled={hasRoutePathOutput}>{children}</RouteTracker>
|
||||
</AnalyticsContext>
|
||||
|
||||
@@ -21,7 +21,7 @@ describe('createSwappableComponent', () => {
|
||||
it('can be created and read', () => {
|
||||
const { ref } = createSwappableComponent({ id: 'foo' });
|
||||
expect(ref.id).toBe('foo');
|
||||
expect(String(ref)).toBe('ComponentRef{id=foo}');
|
||||
expect(String(ref)).toBe('SwappableComponentRef{id=foo}');
|
||||
});
|
||||
|
||||
it('should allow defining a default component implementation', () => {
|
||||
|
||||
@@ -34,5 +34,5 @@ export * from './wiring';
|
||||
export type {
|
||||
CoreProgressProps,
|
||||
CoreNotFoundErrorPageProps,
|
||||
CoreErrorBoundaryFallbackProps,
|
||||
CoreErrorDisplayProps,
|
||||
} from './types';
|
||||
|
||||
@@ -26,7 +26,7 @@ export type CoreNotFoundErrorPageProps = {
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export type CoreErrorBoundaryFallbackProps = {
|
||||
export type CoreErrorDisplayProps = {
|
||||
plugin?: FrontendPlugin;
|
||||
error: Error;
|
||||
resetError: () => void;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import {
|
||||
NotFoundErrorPage as SwappableNotFoundErrorPage,
|
||||
Progress as SwappableProgress,
|
||||
ErrorBoundary as SwappableErrorBoundary,
|
||||
ErrorDisplay as SwappableErrorDisplay,
|
||||
SwappableComponentBlueprint,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
|
||||
@@ -50,7 +50,7 @@ export const ErrorBoundary = SwappableComponentBlueprint.make({
|
||||
name: 'core.components.errorBoundary',
|
||||
params: define =>
|
||||
define({
|
||||
component: SwappableErrorBoundary,
|
||||
component: SwappableErrorDisplay,
|
||||
loader: () => props => {
|
||||
const { plugin, error, resetError } = props;
|
||||
const title = `Error in ${plugin?.id}`;
|
||||
|
||||
Reference in New Issue
Block a user