refactor: use new plugin type in error boundaries

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2023-11-30 10:51:17 +01:00
parent 08699d8873
commit 951decd2ef
5 changed files with 40 additions and 34 deletions
@@ -14,10 +14,15 @@
* limitations under the License.
*/
import React from 'react';
// TODO: Dependency on MUI should be removed from core packages
import { Button } from '@material-ui/core';
import {
createComponentExtension,
coreComponentsRefs,
} from '@backstage/frontend-plugin-api';
import { ErrorPanel } from '@backstage/core-components';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { components as defaultComponents } from '../../../app-defaults/src/defaults';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
@@ -39,5 +44,18 @@ export const DefaultNotFoundErrorPageComponent = createComponentExtension({
export const DefaultErrorBoundaryComponent = createComponentExtension({
ref: coreComponentsRefs.errorBoundaryFallback,
component: { sync: () => defaultComponents.ErrorBoundaryFallback },
component: {
sync: () => props => {
const { plugin, error, resetError } = props;
const title = `Error in ${plugin?.id}`;
return (
<ErrorPanel title={title} error={error} defaultExpanded>
<Button variant="outlined" onClick={resetError}>
Retry
</Button>
</ErrorPanel>
);
},
},
});
+1 -2
View File
@@ -22,7 +22,6 @@ import { AuthProviderInfo } from '@backstage/core-plugin-api';
import { AuthRequestOptions } from '@backstage/core-plugin-api';
import { BackstageIdentityApi } from '@backstage/core-plugin-api';
import { BackstageIdentityResponse } from '@backstage/core-plugin-api';
import { BackstagePlugin as BackstagePlugin_2 } from '@backstage/core-plugin-api';
import { BackstageUserIdentity } from '@backstage/core-plugin-api';
import { bitbucketAuthApiRef } from '@backstage/core-plugin-api';
import { bitbucketServerAuthApiRef } from '@backstage/core-plugin-api';
@@ -340,7 +339,7 @@ export const coreComponentsRefs: {
// @public (undocumented)
export type CoreErrorBoundaryFallbackComponent = ComponentType<
PropsWithChildren<{
plugin?: BackstagePlugin_2;
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
}>
@@ -15,34 +15,13 @@
*/
import React, { Component, PropsWithChildren } from 'react';
// TODO: Dependency on MUI should be removed from core packages
import { Button } from '@material-ui/core';
import { ErrorPanel } from '@backstage/core-components';
import { BackstagePlugin } from '../wiring';
import { CoreErrorBoundaryFallbackComponent } from '../types';
type DefaultErrorBoundaryFallbackProps = PropsWithChildren<{
type ErrorBoundaryProps = PropsWithChildren<{
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
fallback: CoreErrorBoundaryFallbackComponent;
}>;
const DefaultErrorBoundaryFallback = ({
plugin,
error,
resetError,
}: DefaultErrorBoundaryFallbackProps) => {
const title = `Error in ${plugin?.id}`;
return (
<ErrorPanel title={title} error={error} defaultExpanded>
<Button variant="outlined" onClick={resetError}>
Retry
</Button>
</ErrorPanel>
);
};
type ErrorBoundaryProps = PropsWithChildren<{ plugin?: BackstagePlugin }>;
type ErrorBoundaryState = { error?: Error };
/** @internal */
@@ -62,12 +41,11 @@ export class ErrorBoundary extends Component<
render() {
const { error } = this.state;
const { plugin, children } = this.props;
const { plugin, children, fallback: Fallback } = this.props;
if (error) {
// TODO: use a configurable error boundary fallback
return (
<DefaultErrorBoundaryFallback
<Fallback
plugin={plugin}
error={error}
resetError={this.handleErrorReset}
@@ -20,11 +20,16 @@ import React, {
Suspense,
useEffect,
} from 'react';
import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api';
import {
AnalyticsContext,
useAnalytics,
useApi,
} from '@backstage/core-plugin-api';
import { ErrorBoundary } from './ErrorBoundary';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker';
import { AppNode } from '../apis';
import { AppNode, componentsApiRef } from '../apis';
import { coreComponentsRefs } from './ComponentRef';
type RouteTrackerProps = PropsWithChildren<{
disableTracking?: boolean;
@@ -56,6 +61,12 @@ export interface ExtensionBoundaryProps {
/** @public */
export function ExtensionBoundary(props: ExtensionBoundaryProps) {
const { node, routable, children } = props;
const componentsApi = useApi(componentsApiRef);
const plugin = node.spec.source;
const fallback = componentsApi.getComponent(
coreComponentsRefs.errorBoundaryFallback,
);
// Skipping "routeRef" attribute in the new system, the extension "id" should provide more insight
const attributes = {
@@ -65,7 +76,7 @@ export function ExtensionBoundary(props: ExtensionBoundaryProps) {
return (
<Suspense fallback="Loading...">
<ErrorBoundary plugin={node.spec.source}>
<ErrorBoundary plugin={plugin} fallback={fallback}>
<AnalyticsContext attributes={attributes}>
<RouteTracker disableTracking={!routable}>{children}</RouteTracker>
</AnalyticsContext>
+1 -1
View File
@@ -14,8 +14,8 @@
* limitations under the License.
*/
import { BackstagePlugin } from '@backstage/core-plugin-api';
import { ComponentType, PropsWithChildren } from 'react';
import { BackstagePlugin } from './wiring';
// TODO(Rugvip): This might be a quite useful utility type, maybe add to @backstage/types?
/**