From 75ea6f14c5af80d1ca2e8eabeb491c79229a1336 Mon Sep 17 00:00:00 2001 From: benjdlambert Date: Thu, 7 Aug 2025 10:54:10 +0200 Subject: [PATCH] feat: refactor to error display instead Signed-off-by: benjdlambert --- .../src/compatWrapper/BackwardsCompatProvider.tsx | 4 ++-- .../src/compatWrapper/ForwardsCompatProvider.tsx | 10 +++++----- .../src/compatWrapper/compatWrapper.test.tsx | 6 +++--- .../core-compat-api/src/convertLegacyAppOptions.tsx | 10 ++++------ .../src/apis/definitions/SwappableComponentsApi.ts | 2 +- .../src/components/DefaultSwappableComponents.ts | 9 ++++----- .../src/components/ErrorBoundary.tsx | 11 ++++++----- .../src/components/ExtensionBoundary.tsx | 3 +-- .../src/components/createSwappableComponent.test.tsx | 2 +- packages/frontend-plugin-api/src/index.ts | 2 +- packages/frontend-plugin-api/src/types.ts | 2 +- plugins/app/src/extensions/components.tsx | 4 ++-- 12 files changed, 31 insertions(+), 34 deletions(-) diff --git a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx index 2652aa69cf..6abaa433aa 100644 --- a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx +++ b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx @@ -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 }) => ( - + ); return { diff --git a/packages/core-compat-api/src/compatWrapper/ForwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/ForwardsCompatProvider.tsx index 099cb836bb..a3a686a8d2 100644 --- a/packages/core-compat-api/src/compatWrapper/ForwardsCompatProvider.tsx +++ b/packages/core-compat-api/src/compatWrapper/ForwardsCompatProvider.tsx @@ -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; readonly #NotFoundErrorPage: ComponentType; - readonly #ErrorBoundaryFallback: ComponentType; + readonly #ErrorBoundaryFallback: ComponentType; constructor(app: AppContext) { const components = app.getComponents(); - const ErrorBoundaryFallback = (props: CoreErrorBoundaryFallbackProps) => ( + const ErrorBoundaryFallback = (props: CoreErrorDisplayProps) => ( 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; diff --git a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx index 9accec81a6..8304150303 100644 --- a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx +++ b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx @@ -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()); 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" `); }); diff --git a/packages/core-compat-api/src/convertLegacyAppOptions.tsx b/packages/core-compat-api/src/convertLegacyAppOptions.tsx index 7615027a96..d298cb7bf5 100644 --- a/packages/core-compat-api/src/convertLegacyAppOptions.tsx +++ b/packages/core-compat-api/src/convertLegacyAppOptions.tsx @@ -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( define({ - component: SwappableErrorBoundary, + component: SwappableErrorDisplay, loader: () => componentCompatWrapper(WrappedErrorBoundaryFallback), }), diff --git a/packages/frontend-plugin-api/src/apis/definitions/SwappableComponentsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/SwappableComponentsApi.ts index aeb33afca9..29a9584a91 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/SwappableComponentsApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/SwappableComponentsApi.ts @@ -40,5 +40,5 @@ export interface SwappableComponentsApi { * @public */ export const swappableComponentsApiRef = createApiRef({ - id: 'core.swappableComponents', + id: 'core.swappable-components', }); diff --git a/packages/frontend-plugin-api/src/components/DefaultSwappableComponents.ts b/packages/frontend-plugin-api/src/components/DefaultSwappableComponents.ts index 1ff805ba23..f6cc3345cf 100644 --- a/packages/frontend-plugin-api/src/components/DefaultSwappableComponents.ts +++ b/packages/frontend-plugin-api/src/components/DefaultSwappableComponents.ts @@ -15,7 +15,7 @@ */ import { - CoreErrorBoundaryFallbackProps, + CoreErrorDisplayProps, CoreNotFoundErrorPageProps, CoreProgressProps, } from '../types'; @@ -39,7 +39,6 @@ export const NotFoundErrorPage = /** * @public */ -export const ErrorBoundary = - createSwappableComponent({ - id: 'core.components.errorBoundary', - }); +export const ErrorDisplay = createSwappableComponent({ + id: 'core.components.errorDisplay', +}); diff --git a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx index 8842ff55cc..4cde84ee93 100644 --- a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx @@ -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; }>; 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 ( - ); diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx index e88b26f1ef..823d07240b 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx @@ -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 ( }> - + {children} diff --git a/packages/frontend-plugin-api/src/components/createSwappableComponent.test.tsx b/packages/frontend-plugin-api/src/components/createSwappableComponent.test.tsx index 64d989cdb9..b7871eac3c 100644 --- a/packages/frontend-plugin-api/src/components/createSwappableComponent.test.tsx +++ b/packages/frontend-plugin-api/src/components/createSwappableComponent.test.tsx @@ -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', () => { diff --git a/packages/frontend-plugin-api/src/index.ts b/packages/frontend-plugin-api/src/index.ts index f3c633c959..7d519a79da 100644 --- a/packages/frontend-plugin-api/src/index.ts +++ b/packages/frontend-plugin-api/src/index.ts @@ -34,5 +34,5 @@ export * from './wiring'; export type { CoreProgressProps, CoreNotFoundErrorPageProps, - CoreErrorBoundaryFallbackProps, + CoreErrorDisplayProps, } from './types'; diff --git a/packages/frontend-plugin-api/src/types.ts b/packages/frontend-plugin-api/src/types.ts index 9088a9d772..5a8f6db7a7 100644 --- a/packages/frontend-plugin-api/src/types.ts +++ b/packages/frontend-plugin-api/src/types.ts @@ -26,7 +26,7 @@ export type CoreNotFoundErrorPageProps = { }; /** @public */ -export type CoreErrorBoundaryFallbackProps = { +export type CoreErrorDisplayProps = { plugin?: FrontendPlugin; error: Error; resetError: () => void; diff --git a/plugins/app/src/extensions/components.tsx b/plugins/app/src/extensions/components.tsx index 872630a995..782e457b29 100644 --- a/plugins/app/src/extensions/components.tsx +++ b/plugins/app/src/extensions/components.tsx @@ -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}`;